mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-23 20:58:55 -05:00
Decrease memory footprint of stack and improve stack decoder efficiency.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5723 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
ba6031b855
commit
4f7eb39087
@ -32,7 +32,7 @@ int jelinek(
|
|||||||
unsigned char *symbols, /* Raw deinterleaved input symbols */
|
unsigned char *symbols, /* Raw deinterleaved input symbols */
|
||||||
unsigned int nbits, /* Number of output bits */
|
unsigned int nbits, /* Number of output bits */
|
||||||
unsigned int stacksize,
|
unsigned int stacksize,
|
||||||
struct node *stack,
|
struct snode *stack,
|
||||||
int mettab[2][256], /* Metric table, [sent sym][rx symbol] */
|
int mettab[2][256], /* Metric table, [sent sym][rx symbol] */
|
||||||
unsigned int maxcycles)/* Decoding timeout in cycles per bit */
|
unsigned int maxcycles)/* Decoding timeout in cycles per bit */
|
||||||
{
|
{
|
||||||
@ -51,11 +51,11 @@ int jelinek(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// zero the stack
|
// zero the stack
|
||||||
memset(stack,0,stacksize*sizeof(struct node));
|
memset(stack,0,stacksize*sizeof(struct snode));
|
||||||
|
|
||||||
// initialize the loop variables
|
// initialize the loop variables
|
||||||
unsigned int lsym, highbit, ntail=31;
|
unsigned int lsym, ntail=31;
|
||||||
uint64_t encstate=0, encstate_highbits=0;
|
uint64_t encstate=0;
|
||||||
unsigned int nbuckets=1000;
|
unsigned int nbuckets=1000;
|
||||||
unsigned int low_bucket=nbuckets-1; //will be set on first run-through
|
unsigned int low_bucket=nbuckets-1; //will be set on first run-through
|
||||||
unsigned int high_bucket=0;
|
unsigned int high_bucket=0;
|
||||||
@ -72,20 +72,22 @@ int jelinek(
|
|||||||
/********************* Start the stack decoder *****************/
|
/********************* Start the stack decoder *****************/
|
||||||
for (i=1; i <= ncycles; i++) {
|
for (i=1; i <= ncycles; i++) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("***stackptr=%d, depth=%d, gamma=%d, encstate=%lx, encstate_highbits=%lx\n",
|
printf("***stackptr=%ld, depth=%d, gamma=%d, encstate=%lx, bucket %d, low_bucket %d, high_bucket %d\n",
|
||||||
stackptr, depth, gamma, encstate, encstate_highbits);
|
stackptr, depth, gamma, encstate, bucket, low_bucket, high_bucket);
|
||||||
#endif
|
#endif
|
||||||
// save the highbit of the encoder state and shift to the left, bringing
|
// no need to store more than 7 bytes (56 bits) for encoder state because
|
||||||
// in a 0. This is the encoder state of the daughter node connected
|
// only 50 bits are not 0's.
|
||||||
// to the current node by the "0" branch
|
if( depth < 56 ) {
|
||||||
highbit=encstate>>63;
|
|
||||||
encstate=encstate<<1;
|
encstate=encstate<<1;
|
||||||
if( depth > 63 ) {
|
|
||||||
encstate_highbits=(encstate_highbits<<1)|highbit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get channel symbols associated with the 0 branch
|
// get channel symbols associated with the 0 branch
|
||||||
ENCODE(lsym,encstate); /* 0-branch (LSB is 0) */
|
if( depth < 56 ) {
|
||||||
|
ENCODE(lsym,encstate);
|
||||||
|
} else {
|
||||||
|
ENCODE(lsym,encstate<<(depth-55));
|
||||||
|
}
|
||||||
|
|
||||||
// lsym are the 0-branch channel symbols and 3^lsym are the 1-branch
|
// lsym are the 0-branch channel symbols and 3^lsym are the 1-branch
|
||||||
// channel symbols (due to a special property of our generator polynomials)
|
// channel symbols (due to a special property of our generator polynomials)
|
||||||
totmet0 = gamma+metrics[depth][lsym]; // total metric for 0-branch daughter node
|
totmet0 = gamma+metrics[depth][lsym]; // total metric for 0-branch daughter node
|
||||||
@ -98,7 +100,6 @@ int jelinek(
|
|||||||
|
|
||||||
// place the 0 node on the stack, overwriting the parent (current) node
|
// place the 0 node on the stack, overwriting the parent (current) node
|
||||||
stack[ptr].encstate=encstate;
|
stack[ptr].encstate=encstate;
|
||||||
stack[ptr].encstate_highbits=encstate_highbits;
|
|
||||||
stack[ptr].gamma=totmet0;
|
stack[ptr].gamma=totmet0;
|
||||||
stack[ptr].depth=depth;
|
stack[ptr].depth=depth;
|
||||||
stack[ptr].jpointer=buckets[bucket];
|
stack[ptr].jpointer=buckets[bucket];
|
||||||
@ -123,7 +124,6 @@ int jelinek(
|
|||||||
if( bucket < low_bucket ) low_bucket=bucket;
|
if( bucket < low_bucket ) low_bucket=bucket;
|
||||||
|
|
||||||
stack[ptr].encstate=encstate+1;
|
stack[ptr].encstate=encstate+1;
|
||||||
stack[ptr].encstate_highbits=encstate_highbits;
|
|
||||||
stack[ptr].gamma=totmet1;
|
stack[ptr].gamma=totmet1;
|
||||||
stack[ptr].depth=depth;
|
stack[ptr].depth=depth;
|
||||||
stack[ptr].jpointer=buckets[bucket];
|
stack[ptr].jpointer=buckets[bucket];
|
||||||
@ -139,7 +139,6 @@ int jelinek(
|
|||||||
depth=stack[ptr].depth;
|
depth=stack[ptr].depth;
|
||||||
gamma=stack[ptr].gamma;
|
gamma=stack[ptr].gamma;
|
||||||
encstate=stack[ptr].encstate;
|
encstate=stack[ptr].encstate;
|
||||||
encstate_highbits=stack[ptr].encstate_highbits;
|
|
||||||
|
|
||||||
// we are done if the top entry on the stack is at depth nbits
|
// we are done if the top entry on the stack is at depth nbits
|
||||||
if (depth == nbits) {
|
if (depth == nbits) {
|
||||||
@ -149,22 +148,15 @@ int jelinek(
|
|||||||
|
|
||||||
*cycles = i+1;
|
*cycles = i+1;
|
||||||
*metric = gamma; /* Return final path metric */
|
*metric = gamma; /* Return final path metric */
|
||||||
// printf("cycles %d stackptr=%d, depth=%d, gamma=%d, encstate=%lx, encstate_highbits=%lx\n",
|
|
||||||
// *cycles, stackptr, depth, *metric, encstate, encstate_highbits);
|
|
||||||
|
|
||||||
// 81 bits is an awkward number... shift everything to the right by one
|
// printf("cycles %d stackptr=%d, depth=%d, gamma=%d, encstate=%lx\n",
|
||||||
// bit first
|
// *cycles, stackptr, depth, *metric, encstate);
|
||||||
int highbit_lsb=encstate_highbits&(0x0000000000000001);
|
|
||||||
encstate_highbits=encstate_highbits>>1;
|
for (i=0; i<7; i++) {
|
||||||
encstate=encstate>>1;
|
data[i]=(encstate>>(48-i*8))&(0x00000000000000ff);
|
||||||
if( highbit_lsb == 1 ) {
|
|
||||||
encstate=encstate|(0x8000000000000000);
|
|
||||||
}
|
}
|
||||||
//copy data to output buffer
|
for (i=7; i<11; i++) {
|
||||||
data[0]=encstate_highbits>>8;
|
data[i]=0;
|
||||||
data[1]=encstate_highbits&(0x00000000000000ff);
|
|
||||||
for (i=2; i<10; i++) {
|
|
||||||
data[i]=(encstate>>(56-(i-2)*8))&(0x00000000000000ff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*cycles/nbits >= maxcycles) //timed out
|
if(*cycles/nbits >= maxcycles) //timed out
|
||||||
|
@ -3,15 +3,14 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct node {
|
struct snode {
|
||||||
uint64_t encstate; // Encoder state
|
uint64_t encstate; // Encoder state
|
||||||
uint64_t encstate_highbits; // least significant 50 bits are the data
|
|
||||||
int gamma; // Cumulative metric to this node
|
int gamma; // Cumulative metric to this node
|
||||||
unsigned int depth; // depth of this node
|
unsigned int depth; // depth of this node
|
||||||
unsigned int jpointer;
|
unsigned int jpointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node *stack;
|
struct snode *stack;
|
||||||
|
|
||||||
int jelinek(unsigned int *metric,
|
int jelinek(unsigned int *metric,
|
||||||
unsigned int *cycles,
|
unsigned int *cycles,
|
||||||
@ -19,7 +18,7 @@ int jelinek(unsigned int *metric,
|
|||||||
unsigned char *symbols,
|
unsigned char *symbols,
|
||||||
unsigned int nbits,
|
unsigned int nbits,
|
||||||
unsigned int stacksize,
|
unsigned int stacksize,
|
||||||
struct node *stack,
|
struct snode *stack,
|
||||||
int mettab[2][256],
|
int mettab[2][256],
|
||||||
unsigned int maxcycles);
|
unsigned int maxcycles);
|
||||||
|
|
||||||
|
@ -698,7 +698,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( stackdecoder ) {
|
if( stackdecoder ) {
|
||||||
stack=malloc(stacksize*sizeof(struct node));
|
stack=malloc(stacksize*sizeof(struct snode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( optind+1 > argc) {
|
if( optind+1 > argc) {
|
||||||
|
Loading…
Reference in New Issue
Block a user