diff --git a/lib/common/threading.c b/lib/common/threading.c index 38bbab0d4..b56e594b2 100644 --- a/lib/common/threading.c +++ b/lib/common/threading.c @@ -15,6 +15,12 @@ * This file will hold wrapper for systems, which do not support pthreads */ +/* ====== Compiler specifics ====== */ +#if defined(_MSC_VER) +# pragma warning(disable : 4206) /* disable: C4206: translation unit is empty (when ZSTD_MULTITHREAD is not defined) */ +#endif + + #if defined(ZSTD_MULTITHREAD) && defined(_WIN32) /** diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index de5032271..3674281a4 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -2,11 +2,17 @@ /* ====== Tuning parameters ====== */ #ifndef ZSTDMT_SECTION_LOGSIZE_MIN -#define ZSTDMT_SECTION_LOGSIZE_MIN 20 /*< minimum size for a full compression job (20==2^20==1 MB) */ +# define ZSTDMT_SECTION_LOGSIZE_MIN 20 /*< minimum size for a full compression job (20==2^20==1 MB) */ #endif -/* ====== Dependencies ====== */ +/* ====== Compiler specifics ====== */ +#if defined(_MSC_VER) +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +#endif + + +/* ====== Dependencies ====== */ #include /* malloc */ #include /* memcpy */ #include /* threadpool */ @@ -14,6 +20,8 @@ #include "zstd_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */ #include "zstdmt_compress.h" + +/* ====== Debug ====== */ #if 0 # include @@ -73,7 +81,7 @@ typedef struct buffer_s { static const buffer_t g_nullBuffer = { NULL, 0 }; typedef struct ZSTDMT_bufferPool_s { - unsigned totalBuffers;; + unsigned totalBuffers; unsigned nbBuffers; buffer_t bTable[1]; /* variable size */ } ZSTDMT_bufferPool; @@ -107,10 +115,13 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* pool, size_t bSize) free(buf.start); /* size conditions not respected : scratch this buffer and create a new one */ } /* create new buffer */ - { void* const start = malloc(bSize); + { buffer_t buffer; + void* const start = malloc(bSize); if (start==NULL) bSize = 0; - return (buffer_t) { start, bSize }; /* note : start can be NULL if malloc fails ! */ - } + buffer.start = start; /* note : start can be NULL if malloc fails ! */ + buffer.size = bSize; + return buffer; + } } /* store buffer for later re-use, up to pool capacity */ @@ -336,7 +347,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, for (u=0; ubuffPool, dstBufferCapacity) : (buffer_t){ dst, dstCapacity }; + buffer_t const dstAsBuffer = { dst, dstCapacity }; + buffer_t const dstBuffer = u ? ZSTDMT_getBuffer(mtctx->buffPool, dstBufferCapacity) : dstAsBuffer; ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(mtctx->cctxPool); if ((cctx==NULL) || (dstBuffer.start==NULL)) { diff --git a/programs/bench.c b/programs/bench.c index 7dc98653a..2286ead92 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -95,23 +95,6 @@ static clock_t g_time = 0; exit(error); \ } -/* ************************************* -* Time -***************************************/ -/* for posix only - needs proper detection macros to setup */ -#include -#include - -typedef unsigned long long clock_us_t; -static clock_us_t BMK_clockMicroSec(void) -{ - static clock_t _ticksPerSecond = 0; - if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK); - - { struct tms junk; clock_t newTicks = (clock_t) times(&junk); (void)junk; - return ((((clock_us_t)newTicks)*(1000000))/_ticksPerSecond); } -} - /* ************************************* * Benchmark Parameters @@ -248,7 +231,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, /* Bench */ { U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL); U64 const crcOrig = g_decodeOnly ? 0 : XXH64(srcBuffer, srcSize, 0); - clock_us_t coolTime = BMK_clockMicroSec(); + UTIL_time_t coolTime, coolTick; U64 const maxTime = (g_nbSeconds * TIMELOOP_MICROSEC) + 1; U64 totalCTime=0, totalDTime=0; U32 cCompleted=g_decodeOnly, dCompleted=0; @@ -256,25 +239,28 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const char* const marks[NB_MARKS] = { " |", " /", " =", "\\" }; U32 markNb = 0; + UTIL_initTimer(&coolTick); + UTIL_getTime(&coolTime); DISPLAYLEVEL(2, "\r%79s\r", ""); while (!cCompleted || !dCompleted) { /* overheat protection */ - if (BMK_clockMicroSec() - coolTime > ACTIVEPERIOD_MICROSEC) { + if (UTIL_clockSpanMicro(coolTime, coolTick) > ACTIVEPERIOD_MICROSEC) { DISPLAYLEVEL(2, "\rcooling down ... \r"); UTIL_sleep(COOLPERIOD_SEC); - coolTime = BMK_clockMicroSec(); + UTIL_getTime(&coolTime); } if (!g_decodeOnly) { - clock_us_t clockStart; + UTIL_time_t clockTick, clockStart; /* Compression */ DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize); if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */ UTIL_sleepMilli(1); /* give processor time to other processes */ UTIL_waitForNextTick(ticksPerSecond); - clockStart = BMK_clockMicroSec(); + UTIL_initTimer(&clockTick); + UTIL_getTime(&clockStart); if (!cCompleted) { /* still some time to do compression tests */ ZSTD_parameters zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); @@ -315,9 +301,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, blockTable[blockNb].cSize = rSize; } nbLoops++; - } while (BMK_clockMicroSec() - clockStart < clockLoop); + } while (UTIL_clockSpanMicro(clockStart, clockTick) < clockLoop); ZSTD_freeCDict(cdict); - { clock_us_t const clockSpanMicro = BMK_clockMicroSec() - clockStart; + { U64 const clockSpanMicro = UTIL_clockSpanMicro(clockStart, clockTick); if (clockSpanMicro < fastestC*nbLoops) fastestC = clockSpanMicro / nbLoops; totalCTime += clockSpanMicro; cCompleted = (totalCTime >= maxTime); @@ -347,10 +333,11 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (!dCompleted) { U64 clockLoop = g_nbSeconds ? TIMELOOP_MICROSEC : 1; U32 nbLoops = 0; - clock_us_t clockStart; + UTIL_time_t clockStart, clockTick; ZSTD_DDict* const ddict = ZSTD_createDDict(dictBuffer, dictBufferSize); if (!ddict) EXM_THROW(2, "ZSTD_createDDict() allocation failure"); - clockStart = BMK_clockMicroSec(); + UTIL_initTimer(&clockTick); + UTIL_getTime(&clockStart); do { U32 blockNb; for (blockNb=0; blockNb= maxTime); diff --git a/programs/util.h b/programs/util.h index aaa4b7c1e..651027bae 100644 --- a/programs/util.h +++ b/programs/util.h @@ -95,18 +95,26 @@ extern "C" { /*-**************************************** * Time functions ******************************************/ -#if !defined(_WIN32) - typedef clock_t UTIL_time_t; - UTIL_STATIC void UTIL_initTimer(UTIL_time_t* ticksPerSecond) { *ticksPerSecond=0; } - UTIL_STATIC void UTIL_getTime(UTIL_time_t* x) { *x = clock(); } - UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { (void)ticksPerSecond; return 1000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; } - UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { (void)ticksPerSecond; return 1000000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; } -#else +#if (PLATFORM_POSIX_VERSION >= 1) +#include +#include /* times */ + typedef U64 UTIL_time_t; + UTIL_STATIC void UTIL_initTimer(UTIL_time_t* ticksPerSecond) { *ticksPerSecond=sysconf(_SC_CLK_TCK); } + UTIL_STATIC void UTIL_getTime(UTIL_time_t* x) { struct tms junk; clock_t newTicks = (clock_t) times(&junk); (void)junk; *x = (UTIL_time_t)newTicks; } + UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000ULL * (clockEnd - clockStart) / ticksPerSecond; } + UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000000ULL * (clockEnd - clockStart) / ticksPerSecond; } +#elif defined(_WIN32) /* Windows */ typedef LARGE_INTEGER UTIL_time_t; UTIL_STATIC void UTIL_initTimer(UTIL_time_t* ticksPerSecond) { if (!QueryPerformanceFrequency(ticksPerSecond)) fprintf(stderr, "ERROR: QueryPerformance not present\n"); } UTIL_STATIC void UTIL_getTime(UTIL_time_t* x) { QueryPerformanceCounter(x); } UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart; } UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart; } +#else /* relies on standard C (note : clock_t measurements can be wrong when using multi-threading) */ + typedef clock_t UTIL_time_t; + UTIL_STATIC void UTIL_initTimer(UTIL_time_t* ticksPerSecond) { *ticksPerSecond=0; } + UTIL_STATIC void UTIL_getTime(UTIL_time_t* x) { *x = clock(); } + UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { (void)ticksPerSecond; return 1000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; } + UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { (void)ticksPerSecond; return 1000000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; } #endif