bzip2: eliminate some divisions

This commit is contained in:
Denis Vlasenko 2007-10-14 07:49:48 +00:00
parent 3f5fdc7572
commit 6a9154b6f6
3 changed files with 51 additions and 35 deletions

View File

@ -246,7 +246,12 @@ void fallbackSort(uint32_t* fmap,
for (i = 0; i < 257; i++) ftab[i] = 0; for (i = 0; i < 257; i++) ftab[i] = 0;
for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
j = ftab[0]; /* bbox: optimized */
for (i = 1; i < 257; i++) {
j += ftab[i];
ftab[i] = j;
}
for (i = 0; i < nblock; i++) { for (i = 0; i < nblock; i++) {
j = eclass8[i]; j = eclass8[i];
@ -255,7 +260,7 @@ void fallbackSort(uint32_t* fmap,
fmap[k] = i; fmap[k] = i;
} }
nBhtab = 2 + (nblock / 32); nBhtab = 2 + ((uint32_t)nblock / 32); /* bbox: unsigned div is easier */
for (i = 0; i < nBhtab; i++) bhtab[i] = 0; for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
for (i = 0; i < 256; i++) SET_BH(ftab[i]); for (i = 0; i < 256; i++) SET_BH(ftab[i]);
@ -768,8 +773,11 @@ void mainSort(uint32_t* ptr,
} }
/*-- Complete the initial radix sort --*/ /*-- Complete the initial radix sort --*/
for (i = 1; i <= 65536; i++) j = ftab[0]; /* bbox: optimized */
ftab[i] += ftab[i-1]; for (i = 1; i <= 65536; i++) {
j += ftab[i];
ftab[i] = j;
}
s = block[0] << 8; s = block[0] << 8;
i = nblock - 1; i = nblock - 1;
@ -812,19 +820,21 @@ void mainSort(uint32_t* ptr,
{ {
int32_t vv; int32_t vv;
/* was: int32_t h = 1; */ /* bbox: was: int32_t h = 1; */
/* do h = 3 * h + 1; while (h <= 256); */ /* do h = 3 * h + 1; while (h <= 256); */
int32_t h = 364; uint32_t h = 364;
do { do {
h = h / 3; /*h = h / 3;*/
h = (h * 171) >> 9; /* bbox: fast h/3 */
for (i = h; i <= 255; i++) { for (i = h; i <= 255; i++) {
vv = runningOrder[i]; vv = runningOrder[i];
j = i; j = i;
while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) { while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) {
runningOrder[j] = runningOrder[j-h]; runningOrder[j] = runningOrder[j-h];
j = j - h; j = j - h;
if (j <= (h - 1)) goto zero; if (j <= (h - 1))
goto zero;
} }
zero: zero:
runningOrder[j] = vv; runningOrder[j] = vv;
@ -974,7 +984,6 @@ void mainSort(uint32_t* ptr,
} }
AssertH(((bbSize-1) >> shifts) <= 65535, 1002); AssertH(((bbSize-1) >> shifts) <= 65535, 1002);
} }
} }
} }
@ -1041,7 +1050,8 @@ void BZ2_blockSort(EState* s)
s->origPtr = -1; s->origPtr = -1;
for (i = 0; i < s->nblock; i++) for (i = 0; i < s->nblock; i++)
if (ptr[i] == 0) { if (ptr[i] == 0) {
s->origPtr = i; break; s->origPtr = i;
break;
}; };
AssertH(s->origPtr != -1, 1003); AssertH(s->origPtr != -1, 1003);

View File

@ -186,7 +186,8 @@ void generateMTFValues(EState* s)
s->mtfFreq[BZ_RUNA]++; s->mtfFreq[BZ_RUNA]++;
} }
if (zPend < 2) break; if (zPend < 2) break;
zPend = (zPend - 2) / 2; zPend = (uint32_t)(zPend - 2) / 2;
/* bbox: unsigned div is easier */
}; };
zPend = 0; zPend = 0;
} }
@ -219,15 +220,18 @@ void generateMTFValues(EState* s)
zPend--; zPend--;
while (1) { while (1) {
if (zPend & 1) { if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++; mtfv[wr] = BZ_RUNB;
wr++;
s->mtfFreq[BZ_RUNB]++; s->mtfFreq[BZ_RUNB]++;
} else { } else {
mtfv[wr] = BZ_RUNA; wr++; mtfv[wr] = BZ_RUNA;
wr++;
s->mtfFreq[BZ_RUNA]++; s->mtfFreq[BZ_RUNA]++;
} }
if (zPend < 2) if (zPend < 2)
break; break;
zPend = (zPend - 2) / 2; zPend = (uint32_t)(zPend - 2) / 2;
/* bbox: unsigned div is easier */
}; };
zPend = 0; zPend = 0;
} }
@ -297,7 +301,7 @@ void sendMTFValues(EState* s)
if (ge > gs if (ge > gs
&& nPart != nGroups && nPart != 1 && nPart != nGroups && nPart != 1
&& ((nGroups - nPart) % 2 == 1) && ((nGroups - nPart) % 2 == 1) /* bbox: can this be replaced by x & 1? */
) { ) {
aFreq -= s->mtfFreq[ge]; aFreq -= s->mtfFreq[ge];
ge--; ge--;

View File

@ -183,6 +183,8 @@ void BZ2_hbMakeCodeLengths(uint8_t *len,
for (i = 1; i <= alphaSize; i++) { for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8; j = weight[i] >> 8;
/* bbox: yes, it is a signed division.
* don't replace with shift! */
j = 1 + (j / 2); j = 1 + (j / 2);
weight[i] = j << 8; weight[i] = j << 8;
} }