updated util's time for Windows compatibility
Correctly measures time on Posix systems when running with Multi-threading Todo : check Windows measurement under multi-threading
This commit is contained in:
parent
458c8a94b4
commit
5fba09fa41
@ -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)
|
||||
|
||||
/**
|
||||
|
@ -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 <stdlib.h> /* malloc */
|
||||
#include <string.h> /* memcpy */
|
||||
#include <pool.h> /* threadpool */
|
||||
@ -14,6 +20,8 @@
|
||||
#include "zstd_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
|
||||
#include "zstdmt_compress.h"
|
||||
|
||||
|
||||
/* ====== Debug ====== */
|
||||
#if 0
|
||||
|
||||
# include <stdio.h>
|
||||
@ -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; u<nbChunks; u++) {
|
||||
size_t const chunkSize = MIN(remainingSrcSize, avgChunkSize);
|
||||
size_t const dstBufferCapacity = u ? ZSTD_compressBound(chunkSize) : dstCapacity;
|
||||
buffer_t const dstBuffer = u ? ZSTDMT_getBuffer(mtctx->buffPool, 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)) {
|
||||
|
@ -95,23 +95,6 @@ static clock_t g_time = 0;
|
||||
exit(error); \
|
||||
}
|
||||
|
||||
/* *************************************
|
||||
* Time
|
||||
***************************************/
|
||||
/* for posix only - needs proper detection macros to setup */
|
||||
#include <unistd.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
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<nbBlocks; blockNb++) {
|
||||
@ -367,9 +354,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
||||
blockTable[blockNb].resSize = regenSize;
|
||||
}
|
||||
nbLoops++;
|
||||
} while (BMK_clockMicroSec() - clockStart < clockLoop);
|
||||
} while (UTIL_clockSpanMicro(clockStart, clockTick) < clockLoop);
|
||||
ZSTD_freeDDict(ddict);
|
||||
{ clock_us_t const clockSpanMicro = BMK_clockMicroSec() - clockStart;
|
||||
{ U64 const clockSpanMicro = UTIL_clockSpanMicro(clockStart, clockTick);
|
||||
if (clockSpanMicro < fastestD*nbLoops) fastestD = clockSpanMicro / nbLoops;
|
||||
totalDTime += clockSpanMicro;
|
||||
dCompleted = (totalDTime >= maxTime);
|
||||
|
@ -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 <unistd.h>
|
||||
#include <sys/times.h> /* 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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user