From fc2afcfa646b5d18185f8829f65ec7938c85953a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 15:40:14 +0100 Subject: [PATCH 01/16] small Cspeed increase --- lib/zstdhc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index d9b587b96bb..d84c19987bb 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -647,7 +647,11 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, offset_2 = offset_1; matchLength = searchMax(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) { ip++; continue; } + if (!matchLength) + { + ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } /* let's try to find a better solution */ start = ip; @@ -793,7 +797,11 @@ size_t ZSTD_HC_compressBlock_greedy(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS { size_t offset=999999; size_t matchLength = ZSTD_HC_HcFindBestMatch_selectMLS(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) { ip++; continue; } + if (!matchLength) + { + ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } while ((ip>anchor) && (ip-offset>ctx->base) && (ip[-1] == ip[-1-offset])) { ip--; } /* catch up */ /* store sequence */ { From eb283710ddff569e3fb4f31e855bdd5edf453de0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 16:33:11 +0100 Subject: [PATCH 02/16] minor greedy CRatio improvement --- lib/zstdhc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index d84c19987bb..a8e6631e845 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -802,7 +802,7 @@ size_t ZSTD_HC_compressBlock_greedy(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } - while ((ip>anchor) && (ip-offset>ctx->base) && (ip[-1] == ip[-1-offset])) { ip--; } /* catch up */ + while ((ip>anchor) && (ip-offset>ctx->base) && (ip[-1] == ip[-1-offset])) { ip--; matchLength++; } /* catch up */ /* store sequence */ { size_t litLength = ip-anchor; From 47cfa9a98539ff0acf31ac2428b90a56e18a1071 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 17:13:46 +0100 Subject: [PATCH 03/16] minor CRatio improvement --- lib/zstdhc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index a8e6631e845..e2dfafc1de7 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -707,6 +707,8 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, } /* store sequence */ + if (offset) + while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ { size_t litLength = start - anchor; if (offset) offset_1 = offset; From 9b8e453713b3941b21f1192df53ea49d3611d6dd Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 18:28:02 +0100 Subject: [PATCH 04/16] minor CRatio improvement --- lib/zstdhc.c | 25 ++++++++++++++++--------- lib/zstdhc_static.h | 4 ++-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index e2dfafc1de7..dbc7a3a9938 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -655,6 +655,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, /* let's try to find a better solution */ start = ip; + while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ while (ipanchor) && (start2-offset2>ctx->base) && (start2[-1] == start2[-1-offset2])) { start2--; ml2++; } /* catch up */ + gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ + gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); if (gain2 > gain1) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2, start = start2; continue; /* search a better one */ } } @@ -694,12 +699,16 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, { size_t offset2=999999; size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); - int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ - int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); + const BYTE* start2 = ip; + int gain1, gain2; + if (ml2) + while ((start2>anchor) && (start2-offset2>ctx->base) && (start2[-1] == start2[-1-offset2])) { start2--; ml2++; } /* catch up */ + gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ + gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); if (gain2 > gain1) { - matchLength = ml2, offset = offset2, start = ip; - continue; + matchLength = ml2, offset = offset2, start = start2; + continue; /* search a better one */ } } } @@ -707,8 +716,6 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, } /* store sequence */ - if (offset) - while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ { size_t litLength = start - anchor; if (offset) offset_1 = offset; diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 52e9bb88df2..63214a1b509 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -111,8 +111,8 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */ { 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */ { 21, 19, 20, 4, 5, ZSTD_HC_lazy }, /* level 9 */ - { 21, 19, 20, 5, 5, ZSTD_HC_lazy }, /* level 10 */ - { 21, 20, 20, 5, 5, ZSTD_HC_lazy }, /* level 11 */ + { 21, 19, 20, 4, 5, ZSTD_HC_lazy2 }, /* level 10 */ + { 21, 20, 21, 4, 5, ZSTD_HC_lazy2 }, /* level 11 */ { 22, 20, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 12 */ { 22, 21, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 14 */ From 628065cf985d65b7dc053fff2fa34de5ea62c9f8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 18:44:54 +0100 Subject: [PATCH 05/16] revert --- lib/zstdhc.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index dbc7a3a9938..e2dfafc1de7 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -655,7 +655,6 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, /* let's try to find a better solution */ start = ip; - while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ while (ipanchor) && (start2-offset2>ctx->base) && (start2[-1] == start2[-1-offset2])) { start2--; ml2++; } /* catch up */ - gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ - gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); + int gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ + int gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); if (gain2 > gain1) { - matchLength = ml2, offset = offset2, start = start2; + matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ } } @@ -699,16 +694,12 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, { size_t offset2=999999; size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); - const BYTE* start2 = ip; - int gain1, gain2; - if (ml2) - while ((start2>anchor) && (start2-offset2>ctx->base) && (start2[-1] == start2[-1-offset2])) { start2--; ml2++; } /* catch up */ - gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ - gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); + int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ + int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if (gain2 > gain1) { - matchLength = ml2, offset = offset2, start = start2; - continue; /* search a better one */ + matchLength = ml2, offset = offset2, start = ip; + continue; } } } @@ -716,6 +707,8 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, } /* store sequence */ + if (offset) + while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ { size_t litLength = start - anchor; if (offset) offset_1 = offset; From a81d9ac42dd1dd291d8863d737f430a91f839574 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 6 Nov 2015 19:03:59 +0100 Subject: [PATCH 06/16] minor bt CSpeed --- lib/zstdhc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index e2dfafc1de7..44819e6f69f 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -346,25 +346,25 @@ static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ - break; /* just drop , to guarantee consistency (miss a bit of compression; if someone knows better, please tell) */ + break; /* just drop, to guarantee consistency (miss a little bit of compression) */ if (match[matchLength] < ip[matchLength]) { /* match is smaller than current */ *smallerPtr = matchIndex; /* update smaller idx */ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ - if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ - matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + if (matchIndex <= btLow) smallerPtr=&dummy32; /* beyond tree size, stop the search */ + matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[1]; } else { /* match is larger than current */ *largerPtr = matchIndex; commonLengthLarger = matchLength; - if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ largerPtr = nextPtr; - matchIndex = nextPtr[0]; + if (matchIndex <= btLow) largerPtr=&dummy32; /* beyond tree size, stop the search */ + matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[0]; } } @@ -412,7 +412,7 @@ size_t ZSTD_HC_insertBtAndFindBestMatch ( if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) bestLength = matchLength, *offsetPtr = current - matchIndex; if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ - break; /* drop, next to null, to guarantee consistency (is there a way to do better ?) */ + break; /* just drop, to guarantee consistency (miss a little bit of compression) */ } if (match[matchLength] < ip[matchLength]) @@ -420,18 +420,18 @@ size_t ZSTD_HC_insertBtAndFindBestMatch ( /* match is smaller than current */ *smallerPtr = matchIndex; /* update smaller idx */ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ - if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ - matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + if (matchIndex <= btLow) smallerPtr=&dummy32; /* beyond tree size, stop the search */ + matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[1]; } else { /* match is larger than current */ *largerPtr = matchIndex; commonLengthLarger = matchLength; - if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ largerPtr = nextPtr; - matchIndex = nextPtr[0]; + if (matchIndex <= btLow) largerPtr=&dummy32; /* beyond tree size, stop the search */ + matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[0]; } } From f48e35c2068c6843506dd8eb974ffa4d6cd8a690 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 7 Nov 2015 01:13:31 +0100 Subject: [PATCH 07/16] minor bt improvements --- Makefile | 2 +- NEWS | 3 +++ lib/zstd.h | 2 +- lib/zstdhc.c | 50 +++++++++++++++++++++++++++++++-------------- lib/zstdhc_static.h | 2 +- programs/Makefile | 2 +- programs/zstdcli.c | 2 +- 7 files changed, 43 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 7c3fab5ab9e..2003da90cf2 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ # ################################################################ # Version number -export VERSION := 0.3.4 +export VERSION := 0.3.5 PRGDIR = programs ZSTDDIR = lib diff --git a/NEWS b/NEWS index 1c7facdcc1a..a5e18c12dcb 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +v0.3.5 +minor generic compression improvements + v0.3.4 Faster fast cLevels diff --git a/lib/zstd.h b/lib/zstd.h index 115046df872..b13400ecd41 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -48,7 +48,7 @@ extern "C" { ***************************************/ #define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */ #define ZSTD_VERSION_MINOR 3 /* for new (non-breaking) interface capabilities */ -#define ZSTD_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */ +#define ZSTD_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) unsigned ZSTD_versionNumber (void); diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 44819e6f69f..c1e7dcf6ee8 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -161,7 +161,7 @@ static size_t ZSTD_HC_resetCCtx_advanced (ZSTD_HC_CCtx* zc, zc->seqStore.buffer = (void*) (zc->contentTable + ((size_t)1 << contentLog)); } - zc->nextToUpdate = 0; + zc->nextToUpdate = 1; zc->end = NULL; zc->base = NULL; zc->dictBase = NULL; @@ -316,7 +316,7 @@ size_t ZSTD_HC_compressBlock_fast(ZSTD_HC_CCtx* ctx, ***************************************/ /** ZSTD_HC_insertBt1 : add one ptr to tree @ip : assumed <= iend-8 */ -static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares) +static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, const BYTE* const iend, U32 nbCompares) { U32* const hashTable = zc->hashTable; const U32 hashLog = zc->params.hashLog; @@ -327,48 +327,61 @@ static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 U32 matchIndex = hashTable[h]; size_t commonLengthSmaller=0, commonLengthLarger=0; const BYTE* const base = zc->base; - const U32 current = (U32)(ip-base); + const BYTE* match = base + matchIndex; + U32 current = (U32)(ip-base); const U32 btLow = btMask >= current ? 0 : current - btMask; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; U32 dummy32; /* to be nullified at the end */ const U32 windowSize = 1 << zc->params.windowLog; const U32 windowLow = windowSize >= current ? 0 : current - windowSize; + U32 skip = 0; - hashTable[h] = (U32)(ip-base); /* Update Hash Table */ + if ( (current-matchIndex == 1) /* RLE */ + && ZSTD_read_ARCH(match) == ZSTD_read_ARCH(ip)) + { + size_t cyclicLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t); + skip = (U32)(cyclicLength - mls); /* > 1 */ + ip += skip; /* last of segment */ + smallerPtr += 2*skip; + largerPtr += 2*skip; + } + + hashTable[h] = (U32)(ip - base); /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { U32* nextPtr = bt + 2*(matchIndex & btMask); - const BYTE* match = base + matchIndex; size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + match = base + matchIndex; matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ - break; /* just drop, to guarantee consistency (miss a little bit of compression) */ + break; /* just drop , to guarantee consistency (miss a bit of compression; if someone knows better, please tell) */ if (match[matchLength] < ip[matchLength]) { /* match is smaller than current */ *smallerPtr = matchIndex; /* update smaller idx */ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ - if (matchIndex <= btLow) smallerPtr=&dummy32; /* beyond tree size, stop the search */ - matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[1]; + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ } else { /* match is larger than current */ *largerPtr = matchIndex; commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ largerPtr = nextPtr; - if (matchIndex <= btLow) largerPtr=&dummy32; /* beyond tree size, stop the search */ - matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[0]; + matchIndex = nextPtr[0]; } } *smallerPtr = *largerPtr = 0; + return skip+1; } @@ -443,18 +456,19 @@ size_t ZSTD_HC_insertBtAndFindBestMatch ( } -static void ZSTD_HC_updateTree(ZSTD_HC_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls) +static const BYTE* ZSTD_HC_updateTree(ZSTD_HC_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls) { const BYTE* const base = zc->base; const U32 target = (U32)(ip - base); U32 idx = zc->nextToUpdate; //size_t dummy; - for( ; idx < target ; idx++) - ZSTD_HC_insertBt1(zc, base+idx, mls, iend, nbCompares); + for( ; idx < target ; ) + idx += ZSTD_HC_insertBt1(zc, base+idx, mls, iend, nbCompares); //ZSTD_HC_insertBtAndFindBestMatch(zc, base+idx, iend, &dummy, nbCompares, mls); - zc->nextToUpdate = target; + zc->nextToUpdate = idx; + return base + idx; } @@ -466,7 +480,13 @@ size_t ZSTD_HC_BtFindBestMatch ( size_t* offsetPtr, const U32 maxNbAttempts, const U32 mls) { - ZSTD_HC_updateTree(zc, ip, iLimit, maxNbAttempts, mls); + const BYTE* nextToUpdate = ZSTD_HC_updateTree(zc, ip, iLimit, maxNbAttempts, mls); + if (nextToUpdate > ip) + { + /* RLE data */ + *offsetPtr = 1; + return ZSTD_count(ip, ip-1, iLimit); + } return ZSTD_HC_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls); } diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 63214a1b509..8f5f903ecd1 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -106,7 +106,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 19, 15, 16, 1, 6, ZSTD_HC_fast }, /* level 2 */ { 20, 18, 20, 1, 6, ZSTD_HC_fast }, /* level 3 */ { 21, 19, 21, 1, 6, ZSTD_HC_fast }, /* level 4 */ - { 19, 14, 19, 2, 5, ZSTD_HC_greedy }, /* level 5 */ + { 19, 15, 18, 2, 5, ZSTD_HC_greedy }, /* level 5 */ { 20, 17, 19, 3, 5, ZSTD_HC_greedy }, /* level 6 */ { 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */ { 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */ diff --git a/programs/Makefile b/programs/Makefile index c3a250e57ae..ea51bbf7fe3 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -30,7 +30,7 @@ # fullbench32: Same as fullbench, but forced to compile in 32-bits mode # ########################################################################## -VERSION?= 0.3.4 +VERSION?= 0.3.5 DESTDIR?= PREFIX ?= /usr/local diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 2cb59c76b6e..c9946c4deea 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -70,7 +70,7 @@ **************************************/ #define COMPRESSOR_NAME "zstd command line interface" #ifndef ZSTD_VERSION -# define ZSTD_VERSION "v0.3.4" +# define ZSTD_VERSION "v0.3.5" #endif #define AUTHOR "Yann Collet" #define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), ZSTD_VERSION, AUTHOR, __DATE__ From 72a8e751f439cd92d779212025b5a386af437aa2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 7 Nov 2015 22:24:46 +0100 Subject: [PATCH 08/16] level tuning --- lib/zstdhc_static.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 8f5f903ecd1..5a4412e5743 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -106,26 +106,25 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 19, 15, 16, 1, 6, ZSTD_HC_fast }, /* level 2 */ { 20, 18, 20, 1, 6, ZSTD_HC_fast }, /* level 3 */ { 21, 19, 21, 1, 6, ZSTD_HC_fast }, /* level 4 */ - { 19, 15, 18, 2, 5, ZSTD_HC_greedy }, /* level 5 */ + { 20, 13, 18, 4, 5, ZSTD_HC_greedy }, /* level 5 */ { 20, 17, 19, 3, 5, ZSTD_HC_greedy }, /* level 6 */ { 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */ { 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */ - { 21, 19, 20, 4, 5, ZSTD_HC_lazy }, /* level 9 */ + { 21, 20, 20, 3, 5, ZSTD_HC_lazy2 }, /* level 9 */ { 21, 19, 20, 4, 5, ZSTD_HC_lazy2 }, /* level 10 */ - { 21, 20, 21, 4, 5, ZSTD_HC_lazy2 }, /* level 11 */ + { 22, 20, 22, 4, 5, ZSTD_HC_lazy2 }, /* level 11 */ { 22, 20, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 12 */ { 22, 21, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 14 */ { 22, 21, 22, 6, 5, ZSTD_HC_lazy2 }, /* level 15 */ - { 22, 21, 22, 4, 5, ZSTD_HC_btlazy2 }, /* level 16 */ - { 23, 23, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */ + { 23, 21, 22, 5, 5, ZSTD_HC_btlazy2 }, /* level 16 */ + { 23, 24, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */ { 25, 24, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 18 */ { 25, 26, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 19 */ { 26, 27, 24, 6, 5, ZSTD_HC_btlazy2 }, /* level 20 */ }; - #if defined (__cplusplus) } #endif From 31d00ba4b31646996d5ea2153cb5db27a4bd9b8b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 8 Nov 2015 14:11:29 +0100 Subject: [PATCH 09/16] fix bt bug --- lib/zstdhc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index c1e7dcf6ee8..95c40153a32 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -329,7 +329,7 @@ static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, co const BYTE* const base = zc->base; const BYTE* match = base + matchIndex; U32 current = (U32)(ip-base); - const U32 btLow = btMask >= current ? 0 : current - btMask; + U32 btLow = btMask >= current ? 0 : current - btMask; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; U32 dummy32; /* to be nullified at the end */ @@ -343,8 +343,9 @@ static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, co size_t cyclicLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t); skip = (U32)(cyclicLength - mls); /* > 1 */ ip += skip; /* last of segment */ - smallerPtr += 2*skip; - largerPtr += 2*skip; + smallerPtr = bt + 2*((current+skip) & btMask); + largerPtr = bt + 2*((current+skip) & btMask) + 1; + btLow += skip; } hashTable[h] = (U32)(ip - base); /* Update Hash Table */ From 4c7aae3a3676ca299debdcaafce57fe7c1161342 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 8 Nov 2015 14:24:59 +0100 Subject: [PATCH 10/16] fuzzer tests more HC levels --- programs/fuzzer.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/programs/fuzzer.c b/programs/fuzzer.c index 217c829296b..ba402e71a34 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -297,7 +297,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit { size_t sampleSize, sampleStart; size_t cSize, dSize, dSupSize; - U32 sampleSizeLog, buffNb; + U32 sampleSizeLog, buffNb, cLevelMod; U64 crcOrig, crcDest; int cLevel; @@ -328,13 +328,10 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize); crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0); - /* compression test */ - /* covered by HC cLevel 1 - cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize); - CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); */ - /* HC compression test */ - cLevel = (FUZ_rand(&lseed) & 3) +1; +#define MAX(a,b) ((a)>(b)?(a):(b)) + cLevelMod = MAX(1, 38 - (int)(MAX(9, sampleSizeLog) * 2)); /* use high compression levels with small samples, for speed */ + cLevel = (FUZ_rand(&lseed) % cLevelMod) +1; cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel); CHECK(ZSTD_isError(cSize), "ZSTD_HC_compressCCtx failed"); From d61ddd03ec2232aa7b4c80bd0068030f7179aea4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 8 Nov 2015 14:45:38 +0100 Subject: [PATCH 11/16] pg display CL-compatible params --- programs/paramgrill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/paramgrill.c b/programs/paramgrill.c index 520acc1e107..493d806b9e8 100644 --- a/programs/paramgrill.c +++ b/programs/paramgrill.c @@ -289,7 +289,7 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr, U64 crcOrig; /* Memory allocation & restrictions */ - snprintf(name, 30, "W%02uC%02uH%02uS%02uL%1ust%1u", Wlog, Clog, Hlog, Slog, Slength, strat); + snprintf(name, 30, "Sw%02uc%02uh%02us%02ul%1ut%1u", Wlog, Clog, Hlog, Slog, Slength, strat); if (!compressedBuffer || !resultBuffer || !blockTable) { DISPLAY("\nError: not enough memory!\n"); From e9eba608c2c10426b86e29145e9b0e942e708049 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 8 Nov 2015 15:08:03 +0100 Subject: [PATCH 12/16] simplified bt --- lib/zstdhc.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 95c40153a32..76b9dcb195f 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -316,7 +316,7 @@ size_t ZSTD_HC_compressBlock_fast(ZSTD_HC_CCtx* ctx, ***************************************/ /** ZSTD_HC_insertBt1 : add one ptr to tree @ip : assumed <= iend-8 */ -static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, const BYTE* const iend, U32 nbCompares) +static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares) { U32* const hashTable = zc->hashTable; const U32 hashLog = zc->params.hashLog; @@ -329,23 +329,18 @@ static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, co const BYTE* const base = zc->base; const BYTE* match = base + matchIndex; U32 current = (U32)(ip-base); - U32 btLow = btMask >= current ? 0 : current - btMask; + const U32 btLow = btMask >= current ? 0 : current - btMask; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; U32 dummy32; /* to be nullified at the end */ const U32 windowSize = 1 << zc->params.windowLog; const U32 windowLow = windowSize >= current ? 0 : current - windowSize; - U32 skip = 0; - if ( (current-matchIndex == 1) /* RLE */ + if ((current-matchIndex == 1) /* RLE */ && ZSTD_read_ARCH(match) == ZSTD_read_ARCH(ip)) { - size_t cyclicLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t); - skip = (U32)(cyclicLength - mls); /* > 1 */ - ip += skip; /* last of segment */ - smallerPtr = bt + 2*((current+skip) & btMask); - largerPtr = bt + 2*((current+skip) & btMask) + 1; - btLow += skip; + size_t rleLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t); + return (U32)(rleLength - mls); } hashTable[h] = (U32)(ip - base); /* Update Hash Table */ @@ -382,7 +377,7 @@ static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* ip, const U32 mls, co } *smallerPtr = *largerPtr = 0; - return skip+1; + return 1; } From d1ade5a61dd54e4e59ab6c7d4f25b72071e2d210 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 8 Nov 2015 15:49:20 +0100 Subject: [PATCH 13/16] fix 32-bits mode --- lib/zstdhc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 76b9dcb195f..6292f5d6c16 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -337,7 +337,7 @@ static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 m const U32 windowLow = windowSize >= current ? 0 : current - windowSize; if ((current-matchIndex == 1) /* RLE */ - && ZSTD_read_ARCH(match) == ZSTD_read_ARCH(ip)) + && MEM_read64(match) == MEM_read64(ip)) { size_t rleLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t); return (U32)(rleLength - mls); From 4baee507289bee64a55f455d406421c5ab97b45c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 03:19:33 +0100 Subject: [PATCH 14/16] fix bug --- lib/zstdhc.c | 34 ++++++++++++++++++---------------- lib/zstdhc_static.h | 4 ++-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 6292f5d6c16..cfc098ac539 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -447,7 +447,6 @@ size_t ZSTD_HC_insertBtAndFindBestMatch ( *smallerPtr = *largerPtr = 0; zc->nextToUpdate = current+1; /* current has been inserted */ - if (bestLength < MINMATCH) return 0; return bestLength; } @@ -562,22 +561,21 @@ size_t ZSTD_HC_HcFindBestMatch ( if (matchIndex >= dictLimit) { match = base + matchIndex; - if ( (match[ml] == ip[ml]) - && (MEM_read32(match) == MEM_read32(ip)) ) /* ensures minimum match of 4 */ + if (match[ml] == ip[ml]) /* potentially better */ { - const size_t mlt = ZSTD_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; + const size_t mlt = ZSTD_count(ip, match, iLimit); if (mlt > ml) //if (((int)(4*mlt) - (int)ZSTD_highbit((U32)(ip-match)+1)) > ((int)(4*ml) - (int)ZSTD_highbit((U32)((*offsetPtr)+1)))) { ml = mlt; *offsetPtr = ip-match; - if (ip+ml >= iLimit) break; + if (ip+mlt >= iLimit) break; } } } else { match = dictBase + matchIndex; - if (MEM_read32(match) == MEM_read32(ip)) + if (MEM_read32(match) == MEM_read32(ip)) /* beware of end of dict */ { size_t mlt; const BYTE* vLimit = ip + (dictLimit - matchIndex); @@ -663,7 +661,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, offset_2 = offset_1; matchLength = searchMax(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; @@ -680,7 +678,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH; int gain2 = (int)(ml2 * 3); int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = 0, start = ip; } { @@ -688,7 +686,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ @@ -704,7 +702,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH; int gain2 = (int)(ml2 * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = 0, start = ip; } { @@ -712,7 +710,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; @@ -722,15 +720,19 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, break; /* nothing found : store previous solution */ } - /* store sequence */ + /* catch up */ if (offset) - while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ + { + while ((start>anchor) && (start>ctx->base+offset) && (start[-1] == start[-1-offset])) + { start--; matchLength++; } + } + + /* store sequence */ { size_t litLength = start - anchor; if (offset) offset_1 = offset; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); - ip = start + matchLength; - anchor = ip; + anchor = ip = start + matchLength; } } @@ -815,7 +817,7 @@ size_t ZSTD_HC_compressBlock_greedy(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS { size_t offset=999999; size_t matchLength = ZSTD_HC_HcFindBestMatch_selectMLS(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 5a4412e5743..f96d4055eff 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -106,7 +106,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 19, 15, 16, 1, 6, ZSTD_HC_fast }, /* level 2 */ { 20, 18, 20, 1, 6, ZSTD_HC_fast }, /* level 3 */ { 21, 19, 21, 1, 6, ZSTD_HC_fast }, /* level 4 */ - { 20, 13, 18, 4, 5, ZSTD_HC_greedy }, /* level 5 */ + { 20, 13, 18, 5, 5, ZSTD_HC_greedy }, /* level 5 */ { 20, 17, 19, 3, 5, ZSTD_HC_greedy }, /* level 6 */ { 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */ { 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */ @@ -116,7 +116,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 22, 20, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 12 */ { 22, 21, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 14 */ - { 22, 21, 22, 6, 5, ZSTD_HC_lazy2 }, /* level 15 */ + { 23, 23, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 15 */ { 23, 21, 22, 5, 5, ZSTD_HC_btlazy2 }, /* level 16 */ { 23, 24, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */ { 25, 24, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 18 */ From 6d2c9e6c62ba46ea8f4b2362527a69d36851045d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 11:39:48 +0100 Subject: [PATCH 15/16] generic param table --- programs/paramgrill.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/programs/paramgrill.c b/programs/paramgrill.c index 493d806b9e8..f1a316d2b8b 100644 --- a/programs/paramgrill.c +++ b/programs/paramgrill.c @@ -579,23 +579,17 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_HC_parameters params, return better; } -#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) -static BYTE g_alreadyTested[ZSTD_HC_WINDOWLOG_MAX+1-ZSTD_HC_WINDOWLOG_MIN] - [ZSTD_HC_CONTENTLOG_MAX+1-ZSTD_HC_CONTENTLOG_MIN] - [ZSTD_HC_HASHLOG_MAX+1-ZSTD_HC_HASHLOG_MIN] - [ZSTD_HC_SEARCHLOG_MAX+1-ZSTD_HC_SEARCHLOG_MIN] - [ZSTD_HC_SEARCHLENGTH_MAX+1-ZSTD_HC_SEARCHLENGTH_MIN] - [ZSTD_HC_btlazy2+1 /* strategy */ ] = {}; /* init to zero */ +#define PARAMTABLELOG 25 +#define PARAMTABLESIZE (1<> 3) & PARAMTABLEMASK] + +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) static void playAround(FILE* f, winnerInfo_t* winners, ZSTD_HC_parameters params, From 7ccff59cb362bbcb0979950332631a32f205fdaf Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 12:07:44 +0100 Subject: [PATCH 16/16] fold fast stats --- programs/paramgrill.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/programs/paramgrill.c b/programs/paramgrill.c index f1a316d2b8b..eb265e22df6 100644 --- a/programs/paramgrill.c +++ b/programs/paramgrill.c @@ -580,13 +580,25 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_HC_parameters params, } +/* nullified useless params, to ensure count stats */ +static ZSTD_HC_parameters* sanitizeParams(ZSTD_HC_parameters params) +{ + g_params = params; + if (params.strategy == ZSTD_HC_fast) + { + g_params.contentLog = 0; + g_params.searchLog = 0; + } + return &g_params; +} + #define PARAMTABLELOG 25 #define PARAMTABLESIZE (1<> 3) & PARAMTABLEMASK] + g_alreadyTested[(XXH64(sanitizeParams(p), sizeof(p), 0) >> 3) & PARAMTABLEMASK] #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) @@ -1025,6 +1037,7 @@ int main(int argc, char** argv) if (*argument=='K') g_blockSize<<=10, argument++; /* allows using KB notation */ if (*argument=='M') g_blockSize<<=20, argument++; if (*argument=='B') argument++; + DISPLAY("using %u KB block size \n", g_blockSize>>10); } break;