summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp3668
1 files changed, 2720 insertions, 948 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
index ecbacbc9c8e..5da9783d4e1 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp
@@ -2,19 +2,24 @@
#include "StdAfx.h"
-#include <stdio.h>
+#include "../../../../C/CpuArch.h"
+
+// #include <stdio.h>
#ifndef _WIN32
+
#define USE_POSIX_TIME
#define USE_POSIX_TIME2
-#endif
+#endif // _WIN32
#ifdef USE_POSIX_TIME
#include <time.h>
+#include <unistd.h>
#ifdef USE_POSIX_TIME2
#include <sys/time.h>
+#include <sys/times.h>
#endif
-#endif
+#endif // USE_POSIX_TIME
#ifdef _WIN32
#define USE_ALLOCA
@@ -29,37 +34,34 @@
#endif
#include "../../../../C/7zCrc.h"
-#include "../../../../C/Alloc.h"
-#include "../../../../C/CpuArch.h"
-
-#include "../../../Windows/System.h"
+#include "../../../../C/RotateDefs.h"
-#ifndef _7ZIP_ST
+#ifndef Z7_ST
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"
#endif
-#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE)
-#define USE_WIN_FILE
-#endif
-
-#ifdef USE_WIN_FILE
+#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileIO.h"
-#endif
-
+#include "../../../Windows/SystemInfo.h"
+#include "../../../Common/MyBuffer2.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
+#include "../../../Common/Wildcard.h"
#include "../../Common/MethodProps.h"
+#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
#include "Bench.h"
using namespace NWindows;
+#ifndef Z7_ST
static const UInt32 k_LZMA = 0x030101;
+#endif
static const UInt64 kComplexInCommands = (UInt64)1 <<
#ifdef UNDER_CE
@@ -68,9 +70,9 @@ static const UInt64 kComplexInCommands = (UInt64)1 <<
34;
#endif
-static const UInt32 kComplexInSeconds = 4;
+static const UInt32 kComplexInMs = 4000;
-static void SetComplexCommands(UInt32 complexInSeconds,
+static void SetComplexCommandsMs(UInt32 complexInMs,
bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands)
{
complexInCommands = kComplexInCommands;
@@ -80,96 +82,80 @@ static void SetComplexCommands(UInt32 complexInSeconds,
cpuFreq = kMinFreq;
if (cpuFreq < kMaxFreq || isSpecifiedFreq)
{
- if (complexInSeconds != 0)
- complexInCommands = complexInSeconds * cpuFreq;
+ if (complexInMs != 0)
+ complexInCommands = complexInMs * cpuFreq / 1000;
else
complexInCommands = cpuFreq >> 2;
}
}
+// const UInt64 kBenchmarkUsageMult = 1000000; // for debug
+static const unsigned kBenchmarkUsageMultBits = 16;
+static const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits;
+
+UInt64 Benchmark_GetUsage_Percents(UInt64 usage)
+{
+ return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult;
+}
+
static const unsigned kNumHashDictBits = 17;
-static const UInt32 kFilterUnpackSize = (48 << 10);
+static const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test
-static const unsigned kOldLzmaDictBits = 30;
+static const unsigned kOldLzmaDictBits = 32;
-static const UInt32 kAdditionalSize = (1 << 16);
+// static const size_t kAdditionalSize = (size_t)1 << 32; // for debug
+static const size_t kAdditionalSize = (size_t)1 << 16;
static const UInt32 kCompressedAdditionalSize = (1 << 10);
-static const UInt32 kMaxLzmaPropSize = 5;
+
+static const UInt32 kMaxMethodPropSize = (1 << 6);
+
+
+#define ALLOC_WITH_HRESULT(_buffer_, _size_) \
+ { (_buffer_)->Alloc(_size_); \
+ if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; }
+
class CBaseRandomGenerator
{
UInt32 A1;
UInt32 A2;
+ UInt32 Salt;
public:
- CBaseRandomGenerator() { Init(); }
+ CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); }
void Init() { A1 = 362436069; A2 = 521288629;}
+ Z7_FORCE_INLINE
UInt32 GetRnd()
{
- return
+ return Salt ^
+ (
((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
- ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) )
+ );
}
};
-static const unsigned kBufferAlignment = 1 << 4;
-
-struct CBenchBuffer
+Z7_NO_INLINE
+static void RandGen(Byte *buf, size_t size)
{
- size_t BufferSize;
-
- #ifdef _WIN32
-
- Byte *Buffer;
-
- CBenchBuffer(): BufferSize(0), Buffer(NULL) {}
- ~CBenchBuffer() { ::MidFree(Buffer); }
-
- void AllocAlignedMask(size_t size, size_t)
- {
- ::MidFree(Buffer);
- BufferSize = 0;
- Buffer = (Byte *)::MidAlloc(size);
- if (Buffer)
- BufferSize = size;
- }
-
- #else
-
- Byte *Buffer;
- Byte *_bufBase;
-
- CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){}
- ~CBenchBuffer() { ::MidFree(_bufBase); }
-
- void AllocAlignedMask(size_t size, size_t alignMask)
+ CBaseRandomGenerator RG;
+ const size_t size4 = size & ~((size_t)3);
+ size_t i;
+ for (i = 0; i < size4; i += 4)
{
- ::MidFree(_bufBase);
- Buffer = NULL;
- BufferSize = 0;
- _bufBase = (Byte *)::MidAlloc(size + alignMask);
-
- if (_bufBase)
- {
- // Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
- Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
- BufferSize = size;
- }
+ const UInt32 v = RG.GetRnd();
+ SetUi32(buf + i, v)
}
-
- #endif
-
- bool Alloc(size_t size)
+ UInt32 v = RG.GetRnd();
+ for (; i < size; i++)
{
- if (Buffer && BufferSize == size)
- return true;
- AllocAlignedMask(size, kBufferAlignment - 1);
- return (Buffer != NULL || size == 0);
+ buf[i] = (Byte)v;
+ v >>= 8;
}
-};
+}
-class CBenchRandomGenerator: public CBenchBuffer
+class CBenchRandomGenerator: public CMidAlignedBuffer
{
static UInt32 GetVal(UInt32 &res, unsigned numBits)
{
@@ -186,27 +172,33 @@ class CBenchRandomGenerator: public CBenchBuffer
public:
- void GenerateSimpleRandom(CBaseRandomGenerator *_RG_)
+ void GenerateSimpleRandom(UInt32 salt)
{
- CBaseRandomGenerator rg = *_RG_;
- const size_t bufSize = BufferSize;
- Byte *buf = Buffer;
+ CBaseRandomGenerator rg(salt);
+ const size_t bufSize = Size();
+ Byte *buf = (Byte *)*this;
for (size_t i = 0; i < bufSize; i++)
buf[i] = (Byte)rg.GetRnd();
- *_RG_ = rg;
}
- void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_)
+ void GenerateLz(unsigned dictBits, UInt32 salt)
{
- CBaseRandomGenerator rg = *_RG_;
- UInt32 pos = 0;
- UInt32 rep0 = 1;
- const size_t bufSize = BufferSize;
- Byte *buf = Buffer;
+ CBaseRandomGenerator rg(salt);
+ size_t pos = 0;
+ size_t rep0 = 1;
+ const size_t bufSize = Size();
+ Byte *buf = (Byte *)*this;
unsigned posBits = 1;
+
+ // printf("\n dictBits = %d\n", (UInt32)dictBits);
+ // printf("\n bufSize = 0x%p\n", (const void *)bufSize);
while (pos < bufSize)
{
+ /*
+ if (pos >= ((UInt32)1 << 31))
+ printf(" %x\n", pos);
+ */
UInt32 r = rg.GetRnd();
if (GetVal(r, 1) == 0 || pos < 1024)
buf[pos++] = (Byte)(r & 0xFF);
@@ -219,7 +211,7 @@ public:
{
len += GetLen(r);
- while (((UInt32)1 << posBits) < pos)
+ while (((size_t)1 << posBits) < pos)
posBits++;
unsigned numBitsMax = dictBits;
@@ -233,11 +225,12 @@ public:
for (;;)
{
- UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
+ const UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
r = rg.GetRnd();
if (ppp > numBitsMax)
continue;
- rep0 = GetVal(r, ppp);
+ // rep0 = GetVal(r, ppp);
+ rep0 = r & (((size_t)1 << ppp) - 1);
if (rep0 < pos)
break;
r = rg.GetRnd();
@@ -245,10 +238,11 @@ public:
rep0++;
}
+ // len *= 300; // for debug
{
- UInt32 rem = (UInt32)bufSize - pos;
+ const size_t rem = bufSize - pos;
if (len > rem)
- len = rem;
+ len = (UInt32)rem;
}
Byte *dest = buf + pos;
const Byte *src = dest - rep0;
@@ -257,51 +251,54 @@ public:
*dest++ = *src++;
}
}
-
- *_RG_ = rg;
+ // printf("\n CRC = %x\n", CrcCalc(buf, bufSize));
}
};
-class CBenchmarkInStream:
- public ISequentialInStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_NOQIB_1(
+ CBenchmarkInStream
+ , ISequentialInStream
+)
const Byte *Data;
size_t Pos;
size_t Size;
public:
- MY_UNKNOWN_IMP
void Init(const Byte *data, size_t size)
{
Data = data;
Size = size;
Pos = 0;
}
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ bool WasFinished() const { return Pos == Size; }
};
-STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
{
- size_t remain = Size - Pos;
- UInt32 kMaxBlockSize = (1 << 20);
+ const UInt32 kMaxBlockSize = (1 << 20);
if (size > kMaxBlockSize)
size = kMaxBlockSize;
+ const size_t remain = Size - Pos;
if (size > remain)
size = (UInt32)remain;
- for (UInt32 i = 0; i < size; i++)
- ((Byte *)data)[i] = Data[Pos + i];
+
+ if (size != 0)
+ memcpy(data, Data + Pos, size);
+
Pos += size;
if (processedSize)
*processedSize = size;
return S_OK;
}
-class CBenchmarkOutStream:
+
+class CBenchmarkOutStream Z7_final:
public ISequentialOutStream,
- public CBenchBuffer,
- public CMyUnknownImp
+ public CMyUnknownImp,
+ public CMidAlignedBuffer
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_IFACE_COM7_IMP(ISequentialOutStream)
// bool _overflow;
public:
size_t Pos;
@@ -319,23 +316,32 @@ public:
Pos = 0;
}
- // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
+ void InitCrc()
+ {
+ Crc = CRC_INIT_VAL;
+ }
- MY_UNKNOWN_IMP
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ void Calc(const void *data, size_t size)
+ {
+ Crc = CrcUpdate(Crc, data, size);
+ }
+
+ size_t GetPos() const { return Pos; }
+
+ // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
};
-STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
- size_t curSize = BufferSize - Pos;
+ size_t curSize = Size() - Pos;
if (curSize > size)
curSize = size;
if (curSize != 0)
{
if (RealCopy)
- memcpy(Buffer + Pos, data, curSize);
+ memcpy(((Byte *)*this) + Pos, data, curSize);
if (CalcCrc)
- Crc = CrcUpdate(Crc, data, curSize);
+ Calc(data, curSize);
Pos += curSize;
}
if (processedSize)
@@ -348,46 +354,51 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p
return S_OK;
}
-class CCrcOutStream:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
+
+Z7_CLASS_IMP_NOQIB_1(
+ CCrcOutStream
+ , ISequentialOutStream
+)
public:
bool CalcCrc;
UInt32 Crc;
- MY_UNKNOWN_IMP
-
- CCrcOutStream(): CalcCrc(true) {};
- void Init() { Crc = CRC_INIT_VAL; }
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ UInt64 Pos;
+
+ CCrcOutStream(): CalcCrc(true) {}
+ void Init() { Crc = CRC_INIT_VAL; Pos = 0; }
+ void Calc(const void *data, size_t size)
+ {
+ Crc = CrcUpdate(Crc, data, size);
+ }
};
-STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
if (CalcCrc)
- Crc = CrcUpdate(Crc, data, size);
+ Calc(data, size);
+ Pos += size;
if (processedSize)
*processedSize = size;
return S_OK;
}
+// #include "../../../../C/My_sys_time.h"
+
static UInt64 GetTimeCount()
{
#ifdef USE_POSIX_TIME
#ifdef USE_POSIX_TIME2
timeval v;
- if (gettimeofday(&v, 0) == 0)
- return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;
+ if (gettimeofday(&v, NULL) == 0)
+ return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec;
return (UInt64)time(NULL) * 1000000;
#else
return time(NULL);
#endif
#else
- /*
LARGE_INTEGER value;
if (::QueryPerformanceCounter(&value))
- return value.QuadPart;
- */
+ return (UInt64)value.QuadPart;
return GetTickCount();
#endif
}
@@ -401,15 +412,14 @@ static UInt64 GetFreq()
return 1;
#endif
#else
- /*
LARGE_INTEGER value;
if (::QueryPerformanceFrequency(&value))
- return value.QuadPart;
- */
+ return (UInt64)value.QuadPart;
return 1000;
#endif
}
+
#ifdef USE_POSIX_TIME
struct CUserTime
@@ -419,58 +429,106 @@ struct CUserTime
void Init()
{
- Prev = clock();
+ // Prev = clock();
+ Sum = 0;
+ Prev = 0;
+ Update();
Sum = 0;
}
- UInt64 GetUserTime()
+ void Update()
{
+ tms t;
+ /* clock_t res = */ times(&t);
+ clock_t newVal = t.tms_utime + t.tms_stime;
+ Sum += (UInt64)(newVal - Prev);
+ Prev = newVal;
+
+ /*
clock_t v = clock();
- Sum += v - Prev;
- Prev = v;
+ if (v != -1)
+ {
+ Sum += v - Prev;
+ Prev = v;
+ }
+ */
+ }
+ UInt64 GetUserTime()
+ {
+ Update();
return Sum;
}
};
#else
-static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
-UInt64 GetWinUserTime()
-{
- FILETIME creationTime, exitTime, kernelTime, userTime;
- if (
- #ifdef UNDER_CE
- ::GetThreadTimes(::GetCurrentThread()
- #else
- ::GetProcessTimes(::GetCurrentProcess()
- #endif
- , &creationTime, &exitTime, &kernelTime, &userTime) != 0)
- return GetTime64(userTime) + GetTime64(kernelTime);
- return (UInt64)GetTickCount() * 10000;
-}
struct CUserTime
{
- UInt64 StartTime;
+ bool UseTick;
+ DWORD Prev_Tick;
+ UInt64 Prev;
+ UInt64 Sum;
- void Init() { StartTime = GetWinUserTime(); }
- UInt64 GetUserTime() { return GetWinUserTime() - StartTime; }
+ void Init()
+ {
+ UseTick = false;
+ Prev_Tick = 0;
+ Prev = 0;
+ Sum = 0;
+ Update();
+ Sum = 0;
+ }
+ UInt64 GetUserTime()
+ {
+ Update();
+ return Sum;
+ }
+ void Update();
};
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
+
+void CUserTime::Update()
+{
+ DWORD new_Tick = GetTickCount();
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+ if (!UseTick &&
+ #ifdef UNDER_CE
+ ::GetThreadTimes(::GetCurrentThread()
+ #else
+ ::GetProcessTimes(::GetCurrentProcess()
+ #endif
+ , &creationTime, &exitTime, &kernelTime, &userTime))
+ {
+ UInt64 newVal = GetTime64(userTime) + GetTime64(kernelTime);
+ Sum += newVal - Prev;
+ Prev = newVal;
+ }
+ else
+ {
+ UseTick = true;
+ Sum += (UInt64)(new_Tick - (DWORD)Prev_Tick) * 10000;
+ }
+ Prev_Tick = new_Tick;
+}
+
+
#endif
static UInt64 GetUserFreq()
{
#ifdef USE_POSIX_TIME
- return CLOCKS_PER_SEC;
+ // return CLOCKS_PER_SEC;
+ return (UInt64)sysconf(_SC_CLK_TCK);
#else
return 10000000;
#endif
}
-class CBenchProgressStatus
+class CBenchProgressStatus Z7_final
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NSynchronization::CCriticalSection CS;
#endif
public:
@@ -478,14 +536,14 @@ public:
bool EncodeMode;
void SetResult(HRESULT res)
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NSynchronization::CCriticalSectionLock lock(CS);
#endif
Res = res;
}
HRESULT GetResult()
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NSynchronization::CCriticalSectionLock lock(CS);
#endif
return Res;
@@ -517,28 +575,44 @@ void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest)
dest.UserTime = UserTime.GetUserTime();
}
-class CBenchProgressInfo:
+class CBenchProgressInfo Z7_final:
public ICompressProgressInfo,
public CMyUnknownImp,
public CBenchInfoCalc
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_IFACE_COM7_IMP(ICompressProgressInfo)
public:
CBenchProgressStatus *Status;
- HRESULT Res;
IBenchCallback *Callback;
- CBenchProgressInfo(): Callback(0) {}
- MY_UNKNOWN_IMP
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+ CBenchProgressInfo(): Callback(NULL) {}
};
-STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+
+Z7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
{
HRESULT res = Status->GetResult();
if (res != S_OK)
return res;
if (!Callback)
return res;
+
+ /*
+ static UInt64 inSizePrev = 0;
+ static UInt64 outSizePrev = 0;
+ UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0;
+ if (inSize) { val1 = *inSize; delta1 = val1 - inSizePrev; inSizePrev = val1; }
+ if (outSize) { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2; }
+ UInt64 percents = delta2 * 1000;
+ if (delta1 != 0)
+ percents /= delta1;
+ printf("=== %7d %7d %7d %7d ratio = %4d\n",
+ (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10),
+ (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10),
+ (unsigned)percents);
+ */
+
CBenchInfo info;
SetFinishTime(info);
if (Status->EncodeMode)
@@ -560,91 +634,168 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
static const unsigned kSubBits = 8;
-static UInt32 GetLogSize(UInt32 size)
+static unsigned GetLogSize(UInt64 size)
+{
+ unsigned i = 0;
+ for (;;)
+ {
+ i++; size >>= 1; if (size == 0) break;
+ }
+ return i;
+}
+
+
+static UInt32 GetLogSize_Sub(UInt64 size)
+{
+ if (size <= 1)
+ return 0;
+ const unsigned i = GetLogSize(size) - 1;
+ UInt32 v;
+ if (i <= kSubBits)
+ v = (UInt32)(size) << (kSubBits - i);
+ else
+ v = (UInt32)(size >> (i - kSubBits));
+ return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1));
+}
+
+
+static UInt64 Get_UInt64_from_double(double v)
{
- for (unsigned i = kSubBits; i < 32; i++)
- for (UInt32 j = 0; j < (1 << kSubBits); j++)
- if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
- return (i << kSubBits) + j;
- return (32 << kSubBits);
+ const UInt64 kMaxVal = (UInt64)1 << 62;
+ if (v > (double)(Int64)kMaxVal)
+ return kMaxVal;
+ return (UInt64)v;
}
-static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+static UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d)
{
- while (v1 > 1000000)
+ if (d == 0)
+ d = 1;
+ const double v =
+ (double)(Int64)m1 *
+ (double)(Int64)m2 /
+ (double)(Int64)d;
+ return Get_UInt64_from_double(v);
+ /*
+ unsigned n1 = GetLogSize(m1);
+ unsigned n2 = GetLogSize(m2);
+ while (n1 + n2 > 64)
{
- v1 >>= 1;
- v2 >>= 1;
+ if (n1 >= n2)
+ {
+ m1 >>= 1;
+ n1--;
+ }
+ else
+ {
+ m2 >>= 1;
+ n2--;
+ }
+ d >>= 1;
}
+
+ if (d == 0)
+ d = 1;
+ return m1 * m2 / d;
+ */
}
+
UInt64 CBenchInfo::GetUsage() const
{
UInt64 userTime = UserTime;
UInt64 userFreq = UserFreq;
UInt64 globalTime = GlobalTime;
UInt64 globalFreq = GlobalFreq;
- NormalizeVals(userTime, userFreq);
- NormalizeVals(globalFreq, globalTime);
+
if (userFreq == 0)
userFreq = 1;
if (globalTime == 0)
globalTime = 1;
- return userTime * globalFreq * 1000000 / userFreq / globalTime;
+
+ const double v =
+ ((double)(Int64)userTime / (double)(Int64)userFreq)
+ * ((double)(Int64)globalFreq / (double)(Int64)globalTime)
+ * (double)(Int64)kBenchmarkUsageMult;
+ return Get_UInt64_from_double(v);
+ /*
+ return MyMultDiv64(
+ MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq),
+ globalFreq, globalTime);
+ */
}
+
UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
{
- UInt64 userTime = UserTime;
- UInt64 userFreq = UserFreq;
- UInt64 globalTime = GlobalTime;
+ if (UserTime == 0)
+ {
+ return 0;
+ // userTime = 1;
+ }
UInt64 globalFreq = GlobalFreq;
- NormalizeVals(userFreq, userTime);
- NormalizeVals(globalTime, globalFreq);
if (globalFreq == 0)
globalFreq = 1;
- if (userTime == 0)
- userTime = 1;
- return userFreq * globalTime / globalFreq * rating / userTime;
+
+ const double v =
+ ((double)(Int64)GlobalTime / (double)(Int64)globalFreq)
+ * ((double)(Int64)UserFreq / (double)(Int64)UserTime)
+ * (double)(Int64)rating;
+ return Get_UInt64_from_double(v);
+ /*
+ return MyMultDiv64(
+ MyMultDiv64(rating, UserFreq, UserTime),
+ GlobalTime, globalFreq);
+ */
}
-static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
+
+UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const
{
- UInt64 elTime = elapsedTime;
- NormalizeVals(freq, elTime);
- if (elTime == 0)
- elTime = 1;
- return value * freq / elTime;
+ return MyMultDiv64(numUnits, GlobalFreq, GlobalTime);
}
-UInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const
+static UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity)
{
- return MyMultDiv64(numCommands, GlobalTime, GlobalFreq);
+ return complexity >= 0 ?
+ size * (UInt32)complexity :
+ size / (UInt32)(-complexity);
}
struct CBenchProps
{
bool LzmaRatingMode;
- UInt32 EncComplex;
- UInt32 DecComplexCompr;
- UInt32 DecComplexUnc;
+ Int32 EncComplex;
+ Int32 DecComplexCompr;
+ Int32 DecComplexUnc;
+
+ unsigned KeySize;
+
+ CBenchProps():
+ LzmaRatingMode(false),
+ KeySize(0)
+ {}
- CBenchProps(): LzmaRatingMode(false) {}
void SetLzmaCompexity();
- UInt64 GeComprCommands(UInt64 unpackSize)
+ UInt64 GetNumCommands_Enc(UInt64 unpackSize) const
{
- return unpackSize * EncComplex;
+ const UInt32 kMinSize = 100;
+ if (unpackSize < kMinSize)
+ unpackSize = kMinSize;
+ return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex);
}
- UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize)
+ UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const
{
- return (packSize * DecComplexCompr + unpackSize * DecComplexUnc);
+ return
+ GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) +
+ GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc);
}
- UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
- UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
+ UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const;
+ UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const;
};
void CBenchProps::SetLzmaCompexity()
@@ -655,63 +806,247 @@ void CBenchProps::SetLzmaCompexity()
LzmaRatingMode = true;
}
-UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+UInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const
{
if (dictSize < (1 << kBenchMinDicLogSize))
dictSize = (1 << kBenchMinDicLogSize);
- UInt64 encComplex = EncComplex;
+ Int32 encComplex = EncComplex;
if (LzmaRatingMode)
{
- UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits);
+ /*
+ for (UInt64 uu = 0; uu < (UInt64)0xf << 60;)
+ {
+ unsigned rr = GetLogSize_Sub(uu);
+ printf("\n%16I64x , log = %4x", uu, rr);
+ uu += 1;
+ uu += uu / 50;
+ }
+ */
+ // throw 1;
+ const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits);
encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
}
- UInt64 numCommands = (UInt64)size * encComplex;
- return MyMultDiv64(numCommands, elapsedTime, freq);
+ const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex);
+ return MyMultDiv64(numCommands, freq, elapsedTime);
}
-UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
+UInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const
{
- UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations;
- return MyMultDiv64(numCommands, elapsedTime, freq);
+ const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations;
+ return MyMultDiv64(numCommands, freq, elapsedTime);
}
-UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+
+
+UInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const
{
CBenchProps props;
props.SetLzmaCompexity();
- return props.GetCompressRating(dictSize, elapsedTime, freq, size);
+ return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations);
}
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
+UInt64 CBenchInfo::GetRating_LzmaDec() const
{
CBenchProps props;
props.SetLzmaCompexity();
- return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations);
+ return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations);
+}
+
+
+#ifndef Z7_ST
+
+#define NUM_CPU_LEVELS_MAX 3
+
+struct CAffinityMode
+{
+ unsigned NumBundleThreads;
+ unsigned NumLevels;
+ unsigned NumCoreThreads;
+ unsigned NumCores;
+ // unsigned DivideNum;
+ UInt32 Sizes[NUM_CPU_LEVELS_MAX];
+
+ void SetLevels(unsigned numCores, unsigned numCoreThreads);
+ DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const;
+ bool NeedAffinity() const { return NumBundleThreads != 0; }
+
+ WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const
+ {
+ if (NeedAffinity())
+ {
+ CCpuSet cpuSet;
+ GetAffinityMask(bundleIndex, &cpuSet);
+ return thread.Create_With_CpuSet(startAddress, parameter, &cpuSet);
+ }
+ return thread.Create(startAddress, parameter);
+ }
+
+ CAffinityMode():
+ NumBundleThreads(0),
+ NumLevels(0),
+ NumCoreThreads(1)
+ // DivideNum(1)
+ {}
+};
+
+void CAffinityMode::SetLevels(unsigned numCores, unsigned numCoreThreads)
+{
+ NumCores = numCores;
+ NumCoreThreads = numCoreThreads;
+ NumLevels = 0;
+ if (numCoreThreads == 0 || numCores == 0 || numCores % numCoreThreads != 0)
+ return;
+ UInt32 c = numCores / numCoreThreads;
+ UInt32 c2 = 1;
+ while ((c & 1) == 0)
+ {
+ c >>= 1;
+ c2 <<= 1;
+ }
+ if (c2 != 1)
+ Sizes[NumLevels++] = c2;
+ if (c != 1)
+ Sizes[NumLevels++] = c;
+ if (numCoreThreads != 1)
+ Sizes[NumLevels++] = numCoreThreads;
+ if (NumLevels == 0)
+ Sizes[NumLevels++] = 1;
+
+ /*
+ printf("\n Cores:");
+ for (unsigned i = 0; i < NumLevels; i++)
+ {
+ printf(" %d", Sizes[i]);
+ }
+ printf("\n");
+ */
+}
+
+
+DWORD_PTR CAffinityMode::GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const
+{
+ CpuSet_Zero(cpuSet);
+
+ if (NumLevels == 0)
+ return 0;
+
+ // printf("\n%2d", bundleIndex);
+
+ /*
+ UInt32 low = 0;
+ if (DivideNum != 1)
+ {
+ low = bundleIndex % DivideNum;
+ bundleIndex /= DivideNum;
+ }
+ */
+
+ UInt32 numGroups = NumCores / NumBundleThreads;
+ UInt32 m = bundleIndex % numGroups;
+ UInt32 v = 0;
+ for (unsigned i = 0; i < NumLevels; i++)
+ {
+ UInt32 size = Sizes[i];
+ while ((size & 1) == 0)
+ {
+ v *= 2;
+ v |= (m & 1);
+ m >>= 1;
+ size >>= 1;
+ }
+ v *= size;
+ v += m % size;
+ m /= size;
+ }
+
+ // UInt32 nb = NumBundleThreads / DivideNum;
+ UInt32 nb = NumBundleThreads;
+
+ DWORD_PTR mask = ((DWORD_PTR)1 << nb) - 1;
+ // v += low;
+ mask <<= v;
+
+ // printf(" %2d %8x \n ", v, (unsigned)mask);
+ #ifdef _WIN32
+ *cpuSet = mask;
+ #else
+ {
+ for (unsigned k = 0; k < nb; k++)
+ CpuSet_Set(cpuSet, v + k);
+ }
+ #endif
+
+ return mask;
}
-struct CEncoderInfo;
-struct CEncoderInfo
+struct CBenchSyncCommon
+{
+ bool ExitMode;
+ NSynchronization::CManualResetEvent StartEvent;
+
+ CBenchSyncCommon(): ExitMode(false) {}
+};
+
+#endif
+
+
+
+enum E_CheckCrcMode
{
- #ifndef _7ZIP_ST
+ k_CheckCrcMode_Never = 0,
+ k_CheckCrcMode_Always = 1,
+ k_CheckCrcMode_FirstPass = 2
+};
+
+class CEncoderInfo;
+
+class CEncoderInfo Z7_final
+{
+ Z7_CLASS_NO_COPY(CEncoderInfo)
+
+public:
+
+ #ifndef Z7_ST
NWindows::CThread thread[2];
+ NSynchronization::CManualResetEvent ReadyEvent;
UInt32 NumDecoderSubThreads;
+ CBenchSyncCommon *Common;
+ UInt32 EncoderIndex;
+ UInt32 NumEncoderInternalThreads;
+ CAffinityMode AffinityMode;
+ bool IsGlobalMtMode; // if more than one benchmark encoder threads
#endif
+
CMyComPtr<ICompressCoder> _encoder;
CMyComPtr<ICompressFilter> _encoderFilter;
CBenchProgressInfo *progressInfoSpec[2];
CMyComPtr<ICompressProgressInfo> progressInfo[2];
UInt64 NumIterations;
+ UInt32 Salt;
+
#ifdef USE_ALLOCA
size_t AllocaSize;
#endif
+ unsigned KeySize;
Byte _key[32];
Byte _iv[16];
+
+ HRESULT Set_Key_and_IV(ICryptoProperties *cp)
+ {
+ RINOK(cp->SetKey(_key, KeySize))
+ return cp->SetInitVector(_iv, sizeof(_iv));
+ }
+
Byte _psw[16];
- bool CheckCrc_Enc;
- bool CheckCrc_Dec;
+
+ bool CheckCrc_Enc; /* = 1, if we want to check packed data crcs after each pass
+ used for filter and usual coders */
+ bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass
+ used only for filter */
+ E_CheckCrcMode CheckCrcMode_Dec;
struct CDecoderInfo
{
@@ -741,28 +1076,41 @@ struct CEncoderInfo
const Byte *fileData;
CBenchRandomGenerator rg;
- CBenchBuffer rgCopy; // it must be 16-byte aligned !!!
- CBenchmarkOutStream *propStreamSpec;
+ CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!!
+
+ // CBenchmarkOutStream *propStreamSpec;
+ Byte propsData[kMaxMethodPropSize];
+ CBufPtrSeqOutStream *propStreamSpec;
CMyComPtr<ISequentialOutStream> propStream;
- // for decode
+ unsigned generateDictBits;
COneMethodInfo _method;
+
+ // for decode
size_t _uncompressedDataSize;
- HRESULT Init(
- const COneMethodInfo &method,
- unsigned generateDictBits,
- CBaseRandomGenerator *rg);
+ HRESULT Generate();
HRESULT Encode();
HRESULT Decode(UInt32 decoderIndex);
CEncoderInfo():
- fileData(NULL),
+ #ifndef Z7_ST
+ Common(NULL),
+ IsGlobalMtMode(true),
+ #endif
+ Salt(0),
+ KeySize(0),
CheckCrc_Enc(true),
- CheckCrc_Dec(true),
- outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
+ UseRealData_Enc(true),
+ CheckCrcMode_Dec(k_CheckCrcMode_Always),
+ outStreamSpec(NULL),
+ callback(NULL),
+ printCallback(NULL),
+ fileData(NULL),
+ propStreamSpec(NULL)
+ {}
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
{
@@ -775,15 +1123,16 @@ struct CEncoderInfo
#endif
res = encoder->Encode();
- encoder->Results[0] = res;
}
catch(...)
{
res = E_FAIL;
}
+ encoder->Results[0] = res;
if (res != S_OK)
encoder->progressInfoSpec[0]->Status->SetResult(res);
- return 0;
+ encoder->ReadyEvent.Set();
+ return THREAD_FUNC_RET_ZERO;
}
static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
@@ -796,12 +1145,18 @@ struct CEncoderInfo
CEncoderInfo *encoder = decoder->Encoder;
encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
- return 0;
+ return THREAD_FUNC_RET_ZERO;
}
HRESULT CreateEncoderThread()
{
- return thread[0].Create(EncodeThreadFunction, this);
+ WRes res = 0;
+ if (!ReadyEvent.IsCreated())
+ res = ReadyEvent.Create();
+ if (res == 0)
+ res = AffinityMode.CreateThread_WithAffinity(thread[0], EncodeThreadFunction, this,
+ EncoderIndex);
+ return HRESULT_FROM_WIN32(res);
}
HRESULT CreateDecoderThread(unsigned index, bool callbackMode
@@ -819,66 +1174,99 @@ struct CEncoderInfo
#endif
decoder.CallbackMode = callbackMode;
- return thread[index].Create(DecodeThreadFunction, &decoder);
+
+ WRes res = AffinityMode.CreateThread_WithAffinity(thread[index], DecodeThreadFunction, &decoder,
+ // EncoderIndex * NumEncoderInternalThreads + index
+ EncoderIndex
+ );
+
+ return HRESULT_FROM_WIN32(res);
}
#endif
};
-HRESULT CEncoderInfo::Init(
- const COneMethodInfo &method,
- unsigned generateDictBits,
- CBaseRandomGenerator *rgLoc)
+
+
+static size_t GetBenchCompressedSize(size_t bufferSize)
+{
+ return kCompressedAdditionalSize + bufferSize + bufferSize / 16;
+ // kBufferSize / 2;
+}
+
+
+HRESULT CEncoderInfo::Generate()
{
+ const COneMethodInfo &method = _method;
+
// we need extra space, if input data is already compressed
- const size_t kCompressedBufferSize =
- kCompressedAdditionalSize +
- kBufferSize + kBufferSize / 16;
- // kBufferSize / 2;
+ const size_t kCompressedBufferSize = _encoderFilter ?
+ kBufferSize :
+ GetBenchCompressedSize(kBufferSize);
if (kCompressedBufferSize < kBufferSize)
return E_FAIL;
uncompressedDataPtr = fileData;
-
- if (!fileData)
+ if (fileData)
{
- if (!rg.Alloc(kBufferSize))
- return E_OUTOFMEMORY;
-
+ #if !defined(Z7_ST)
+ if (IsGlobalMtMode)
+ {
+ /* we copy the data to local buffer of thread to eliminate
+ using of shared buffer by different threads */
+ ALLOC_WITH_HRESULT(&rg, kBufferSize)
+ memcpy((Byte *)rg, fileData, kBufferSize);
+ uncompressedDataPtr = (const Byte *)rg;
+ }
+ #endif
+ }
+ else
+ {
+ ALLOC_WITH_HRESULT(&rg, kBufferSize)
// DWORD ttt = GetTickCount();
if (generateDictBits == 0)
- rg.GenerateSimpleRandom(rgLoc);
+ rg.GenerateSimpleRandom(Salt);
else
- rg.GenerateLz(generateDictBits, rgLoc);
+ {
+ if (generateDictBits >= sizeof(size_t) * 8
+ && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1)))
+ return E_INVALIDARG;
+ rg.GenerateLz(generateDictBits, Salt);
+ // return E_ABORT; // for debug
+ }
// printf("\n%d\n ", GetTickCount() - ttt);
- crc = CrcCalc(rg.Buffer, rg.BufferSize);
- uncompressedDataPtr = rg.Buffer;
+ crc = CrcCalc((const Byte *)rg, rg.Size());
+ uncompressedDataPtr = (const Byte *)rg;
}
-
- if (_encoderFilter)
+
+ if (!outStream)
{
- if (!rgCopy.Alloc(kBufferSize))
- return E_OUTOFMEMORY;
+ outStreamSpec = new CBenchmarkOutStream;
+ outStream = outStreamSpec;
}
+ ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize)
- outStreamSpec = new CBenchmarkOutStream;
- outStream = outStreamSpec;
- if (!outStreamSpec->Alloc(kCompressedBufferSize))
- return E_OUTOFMEMORY;
+ if (_encoderFilter)
+ {
+ /* we try to reduce the number of memcpy() in main encoding loop.
+ so we copy data to temp buffers here */
+ ALLOC_WITH_HRESULT(&rgCopy, kBufferSize)
+ memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize);
+ memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize);
+ }
- propStreamSpec = 0;
if (!propStream)
{
- propStreamSpec = new CBenchmarkOutStream;
+ propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream;
propStream = propStreamSpec;
}
- if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
- return E_OUTOFMEMORY;
- propStreamSpec->Init(true, false);
+ // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize);
+ // propStreamSpec->Init(true, false);
+ propStreamSpec->Init(propsData, sizeof(propsData));
CMyComPtr<IUnknown> coder;
@@ -891,8 +1279,23 @@ HRESULT CEncoderInfo::Init(
coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
if (scp)
{
- UInt64 reduceSize = kBufferSize;
- RINOK(method.SetCoderProps(scp, &reduceSize));
+ const UInt64 reduceSize = kBufferSize;
+
+ /* in posix new thread uses same affinity as parent thread,
+ so we don't need to send affinity to coder in posix */
+ UInt64 affMask;
+ #if !defined(Z7_ST) && defined(_WIN32)
+ {
+ CCpuSet cpuSet;
+ affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet);
+ }
+ #else
+ affMask = 0;
+ #endif
+ // affMask <<= 3; // debug line: to test no affinity in coder;
+ // affMask = 0;
+
+ RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, (affMask != 0 ? &affMask : NULL)))
}
else
{
@@ -904,7 +1307,7 @@ HRESULT CEncoderInfo::Init(
coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
if (writeCoderProps)
{
- RINOK(writeCoderProps->WriteCoderProperties(propStream));
+ RINOK(writeCoderProps->WriteCoderProperties(propStream))
}
{
@@ -912,7 +1315,7 @@ HRESULT CEncoderInfo::Init(
coder.QueryInterface(IID_ICryptoSetPassword, &sp);
if (sp)
{
- RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
+ RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
// we must call encoding one time to calculate password key for key cache.
// it must be after WriteCoderProperties!
@@ -934,7 +1337,7 @@ HRESULT CEncoderInfo::Init(
CMyComPtr<ISequentialOutStream> crcStream = crcStreamSpec;
crcStreamSpec->Init();
- RINOK(_encoder->Code(inStream, crcStream, 0, 0, NULL));
+ RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL))
}
}
}
@@ -944,19 +1347,22 @@ HRESULT CEncoderInfo::Init(
}
-static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size)
+static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc)
{
while (size != 0)
{
- UInt32 cur = (UInt32)1 << 31;
+ UInt32 cur = crc ? 1 << 17 : 1 << 24;
if (cur > size)
cur = (UInt32)size;
UInt32 processed = filter->Filter(data, cur);
- data += processed;
- // if (processed > size) (in AES filter), we must fill last block with zeros.
- // but it is not important for benchmark. So we just copy that data without filtering.
+ /* if (processed > size) (in AES filter), we must fill last block with zeros.
+ but it is not important for benchmark. So we just copy that data without filtering.
+ if (processed == 0) then filter can't process more */
if (processed > size || processed == 0)
- break;
+ processed = (UInt32)size;
+ if (crc)
+ *crc = CrcUpdate(*crc, data, processed);
+ data += processed;
size -= processed;
}
}
@@ -964,6 +1370,32 @@ static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size)
HRESULT CEncoderInfo::Encode()
{
+ // printf("\nCEncoderInfo::Generate\n");
+
+ RINOK(Generate())
+
+ // printf("\n2222\n");
+
+ #ifndef Z7_ST
+ if (Common)
+ {
+ Results[0] = S_OK;
+ WRes wres = ReadyEvent.Set();
+ if (wres == 0)
+ wres = Common->StartEvent.Lock();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ if (Common->ExitMode)
+ return S_OK;
+ }
+ else
+ #endif
+ {
+ CBenchProgressInfo *bpi = progressInfoSpec[0];
+ bpi->SetStartTime();
+ }
+
+
CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
bi.UnpackSize = 0;
bi.PackSize = 0;
@@ -976,52 +1408,116 @@ HRESULT CEncoderInfo::Encode()
coder.QueryInterface(IID_ICryptoProperties, &cp);
CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
- UInt64 prev = 0;
-
- UInt32 crcPrev = 0;
if (cp)
{
- RINOK(cp->SetKey(_key, sizeof(_key)));
- RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ RINOK(Set_Key_and_IV(cp))
+ }
+
+ compressedSize = 0;
+ if (_encoderFilter)
+ compressedSize = kBufferSize;
+
+ // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec;
+ UInt64 prev = 0;
+
+ const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF);
+ const bool useCrc = (mask < NumIterations);
+ bool crcPrev_defined = false;
+ UInt32 crcPrev = 0;
+
+ bool useRealData_Enc = UseRealData_Enc;
+ bool data_Was_Changed = false;
+ if (useRealData_Enc)
+ {
+ /* we want memcpy() for each iteration including first iteration.
+ So results will be equal for different number of iterations */
+ data_Was_Changed = true;
}
- for (UInt64 i = 0; i < NumIterations; i++)
+ const UInt64 numIterations = NumIterations;
+ UInt64 i = numIterations;
+ // printCallback->NewLine();
+
+ while (i != 0)
{
- if (printCallback && bi.UnpackSize - prev > (1 << 20))
+ i--;
+ if (printCallback && bi.UnpackSize - prev >= (1 << 26))
{
- RINOK(printCallback->CheckBreak());
prev = bi.UnpackSize;
+ RINOK(printCallback->CheckBreak())
}
+
+ /*
+ CBenchInfo info;
+ progressInfoSpec[0]->SetStartTime();
+ */
- bool isLast = (i == NumIterations - 1);
- bool calcCrc = ((isLast || (i & 0x7F) == 0 || CheckCrc_Enc) && NumIterations != 1);
- outStreamSpec->Init(isLast, calcCrc);
-
+ bool calcCrc = false;
+ if (useCrc)
+ calcCrc = (((UInt32)i & mask) == 0);
+
if (_encoderFilter)
{
- memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize);
+ Byte *filterData = rgCopy;
+ if (i == numIterations - 1 || calcCrc || useRealData_Enc)
+ {
+ filterData = (Byte *)*outStreamSpec;
+ if (data_Was_Changed)
+ memcpy(filterData, uncompressedDataPtr, kBufferSize);
+ data_Was_Changed = true;
+ }
_encoderFilter->Init();
- My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize);
- RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize));
+ if (calcCrc)
+ outStreamSpec->InitCrc();
+ My_FilterBench(_encoderFilter, filterData, kBufferSize,
+ calcCrc ? &outStreamSpec->Crc : NULL);
}
else
{
+ outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations
inStreamSpec->Init(uncompressedDataPtr, kBufferSize);
- RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]));
+ RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]))
+ if (!inStreamSpec->WasFinished())
+ return E_FAIL;
+ if (compressedSize != outStreamSpec->Pos)
+ {
+ if (compressedSize != 0)
+ return E_FAIL;
+ compressedSize = outStreamSpec->Pos;
+ }
}
// outStreamSpec->Print();
- UInt32 crcNew = CRC_GET_DIGEST(outStreamSpec->Crc);
- if (i == 0)
- crcPrev = crcNew;
- else if (calcCrc && crcPrev != crcNew)
- return E_FAIL;
+ if (calcCrc)
+ {
+ const UInt32 crc2 = CRC_GET_DIGEST(outStreamSpec->Crc);
+ if (crcPrev_defined && crcPrev != crc2)
+ return E_FAIL;
+ crcPrev = crc2;
+ crcPrev_defined = true;
+ }
- compressedSize = outStreamSpec->Pos;
bi.UnpackSize += kBufferSize;
bi.PackSize += compressedSize;
+
+ /*
+ {
+ progressInfoSpec[0]->SetFinishTime(info);
+ info.UnpackSize = 0;
+ info.PackSize = 0;
+ info.NumIterations = 1;
+
+ info.UnpackSize = kBufferSize;
+ info.PackSize = compressedSize;
+ // printf("\n%7d\n", encoder.compressedSize);
+
+ RINOK(callback->SetEncodeResult(info, true))
+ printCallback->NewLine();
+ }
+ */
+
}
_encoder.Release();
@@ -1047,7 +1543,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
- if (!setDecProps && propStreamSpec->Pos != 0)
+ if (!setDecProps && propStreamSpec->GetPos() != 0)
return E_FAIL;
CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
@@ -1057,13 +1553,13 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
pi->BenchInfo.UnpackSize = 0;
pi->BenchInfo.PackSize = 0;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
- RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads));
+ RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads))
}
}
#endif
@@ -1072,8 +1568,8 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
if (scp)
{
- UInt64 reduceSize = _uncompressedDataSize;
- RINOK(_method.SetCoderProps(scp, &reduceSize));
+ const UInt64 reduceSize = _uncompressedDataSize;
+ RINOK(_method.SetCoderProps(scp, &reduceSize))
}
CMyComPtr<ICryptoProperties> cp;
@@ -1081,7 +1577,10 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
if (setDecProps)
{
- RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos));
+ RINOK(setDecProps->SetDecoderProperties2(
+ /* (const Byte *)*propStreamSpec, */
+ propsData,
+ (UInt32)propStreamSpec->GetPos()))
}
{
@@ -1089,7 +1588,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
coder.QueryInterface(IID_ICryptoSetPassword, &sp);
if (sp)
{
- RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
+ RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
}
}
@@ -1097,40 +1596,90 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
if (cp)
{
- RINOK(cp->SetKey(_key, sizeof(_key)));
- RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ RINOK(Set_Key_and_IV(cp))
}
- for (UInt64 i = 0; i < NumIterations; i++)
+ CMyComPtr<ICompressSetFinishMode> setFinishMode;
+
+ if (_decoderFilter)
{
- if (printCallback && pi->BenchInfo.UnpackSize - prev > (1 << 20))
+ if (compressedSize > rgCopy.Size())
+ return E_FAIL;
+ }
+ else
+ {
+ decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
+ }
+
+ const UInt64 numIterations = NumIterations;
+ const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec;
+
+ for (UInt64 i = 0; i < numIterations; i++)
+ {
+ if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26))
{
- RINOK(printCallback->CheckBreak());
+ RINOK(printCallback->CheckBreak())
prev = pi->BenchInfo.UnpackSize;
}
- inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+ const UInt64 outSize = kBufferSize;
+ bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never);
+
crcOutStreamSpec->Init();
-
- UInt64 outSize = kBufferSize;
- crcOutStreamSpec->CalcCrc = ((i & 0x7F) == 0 || CheckCrc_Dec);
-
+
if (_decoderFilter)
{
- if (compressedSize > rgCopy.BufferSize)
- return E_FAIL;
- memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize);
+ Byte *filterData = (Byte *)*outStreamSpec;
+ if (calcCrc)
+ {
+ calcCrc = (i == 0);
+ if (checkCrcMode == k_CheckCrcMode_Always)
+ {
+ calcCrc = true;
+ memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize);
+ filterData = rgCopy;
+ }
+ }
_decoderFilter->Init();
- My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize);
- RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize));
+ My_FilterBench(_decoderFilter, filterData, compressedSize,
+ calcCrc ? &crcOutStreamSpec->Crc : NULL);
}
else
{
- RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
+ crcOutStreamSpec->CalcCrc = calcCrc;
+ inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize);
+
+ if (setFinishMode)
+ {
+ RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)))
+ }
+
+ RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex]))
+
+ if (setFinishMode)
+ {
+ if (!inStreamSpec->WasFinished())
+ return S_FALSE;
+
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
+
+ if (getInStreamProcessedSize)
+ {
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
+ if (processed != compressedSize)
+ return S_FALSE;
+ }
+ }
+
+ if (crcOutStreamSpec->Pos != outSize)
+ return S_FALSE;
}
- if (crcOutStreamSpec->CalcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
+ if (calcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
return S_FALSE;
+
pi->BenchInfo.UnpackSize += kBufferSize;
pi->BenchInfo.PackSize += compressedSize;
}
@@ -1146,7 +1695,7 @@ static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
{
CEncoderInfo *encoders;
- CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
+ CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
~CBenchEncoders() { delete []encoders; }
};
@@ -1160,19 +1709,74 @@ static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
}
+
+#ifndef Z7_ST
+
+// ---------- CBenchThreadsFlusher ----------
+
+struct CBenchThreadsFlusher
+{
+ CBenchEncoders *EncodersSpec;
+ CBenchSyncCommon Common;
+ unsigned NumThreads;
+ bool NeedClose;
+
+ CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {}
+
+ ~CBenchThreadsFlusher()
+ {
+ StartAndWait(true);
+ }
+
+ WRes StartAndWait(bool exitMode = false);
+};
+
+
+WRes CBenchThreadsFlusher::StartAndWait(bool exitMode)
+{
+ if (!NeedClose)
+ return 0;
+
+ Common.ExitMode = exitMode;
+ WRes res = Common.StartEvent.Set();
+
+ for (unsigned i = 0; i < NumThreads; i++)
+ {
+ NWindows::CThread &t = EncodersSpec->encoders[i].thread[0];
+ if (t.IsCreated())
+ {
+ WRes res2 = t.Wait_Close();
+ if (res == 0)
+ res = res2;
+ }
+ }
+ NeedClose = false;
+ return res;
+}
+
+#endif // Z7_ST
+
+
+
+static void SetPseudoRand(Byte *data, size_t size, UInt32 startValue)
+{
+ for (size_t i = 0; i < size; i++)
+ {
+ data[i] = (Byte)startValue;
+ startValue++;
+ }
+}
+
+
+
static HRESULT MethodBench(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 complexInCommands,
- bool
- #ifndef _7ZIP_ST
- oldLzmaBenchMode
- #endif
- ,
- UInt32
- #ifndef _7ZIP_ST
- numThreads
- #endif
- ,
+ #ifndef Z7_ST
+ bool oldLzmaBenchMode,
+ UInt32 numThreads,
+ const CAffinityMode *affinityMode,
+ #endif
const COneMethodInfo &method2,
size_t uncompressedDataSize,
const Byte *fileData,
@@ -1185,9 +1789,12 @@ static HRESULT MethodBench(
COneMethodInfo method = method2;
UInt64 methodId;
UInt32 numStreams;
- if (!FindMethod(
+ bool isFilter;
+ const int codecIndex = FindMethod_Index(
EXTERNAL_CODECS_LOC_VARS
- method.MethodName, methodId, numStreams))
+ method.MethodName, true,
+ methodId, numStreams, isFilter);
+ if (codecIndex < 0)
return E_NOTIMPL;
if (numStreams != 1)
return E_INVALIDARG;
@@ -1195,21 +1802,24 @@ static HRESULT MethodBench(
UInt32 numEncoderThreads = 1;
UInt32 numSubDecoderThreads = 1;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
numEncoderThreads = numThreads;
- if (oldLzmaBenchMode && methodId == k_LZMA)
+ if (oldLzmaBenchMode)
+ if (methodId == k_LZMA)
{
- bool fixedNumber;
- UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
- if (!fixedNumber && numThreads == 1)
+ if (numThreads == 1 && method.Get_NumThreads() < 0)
method.AddProp_NumThreads(1);
+ const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads();
if (numThreads > 1 && numLzmaThreads > 1)
{
- numEncoderThreads = numThreads / 2;
+ numEncoderThreads = (numThreads + 1) / 2; // 20.03
numSubDecoderThreads = 2;
}
}
+
+ const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity();
+
#endif
CBenchEncoders encodersSpec(numEncoderThreads);
@@ -1220,37 +1830,65 @@ static HRESULT MethodBench(
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
- encoder.callback = (i == 0) ? callback : 0;
+ encoder.callback = (i == 0) ? callback : NULL;
encoder.printCallback = printCallback;
+ #ifndef Z7_ST
+ encoder.EncoderIndex = i;
+ encoder.NumEncoderInternalThreads = numSubDecoderThreads;
+ encoder.AffinityMode = *affinityMode;
+
+ /*
+ if (numSubDecoderThreads > 1)
+ if (encoder.AffinityMode.NeedAffinity()
+ && encoder.AffinityMode.NumBundleThreads == 1)
+ {
+ // if old LZMA benchmark uses two threads in coder, we increase (NumBundleThreads) for old LZMA benchmark uses two threads instead of one
+ if (encoder.AffinityMode.NumBundleThreads * 2 <= encoder.AffinityMode.NumCores)
+ encoder.AffinityMode.NumBundleThreads *= 2;
+ }
+ */
+
+ #endif
+
{
CCreatedCoder cod;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod));
+ RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod))
encoder._encoder = cod.Coder;
if (!encoder._encoder && !encoder._encoderFilter)
return E_NOTIMPL;
}
- encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30 ;
- encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30 ;
-
- memset(encoder._iv, 0, sizeof(encoder._iv));
- memset(encoder._key, 0, sizeof(encoder._key));
- memset(encoder._psw, 0, sizeof(encoder._psw));
+ SetPseudoRand(encoder._iv, sizeof(encoder._iv), 17);
+ SetPseudoRand(encoder._key, sizeof(encoder._key), 51);
+ SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123);
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
CCreatedCoder cod;
CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
+ RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod))
decoder = cod.Coder;
if (!encoder._decoderFilter && !decoder)
return E_NOTIMPL;
}
- }
- CBaseRandomGenerator rg;
- rg.Init();
+ encoder.UseRealData_Enc =
+ encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30;
+
+ encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
+ if (benchProps->DecComplexCompr +
+ benchProps->DecComplexUnc <= 30)
+ encoder.CheckCrcMode_Dec =
+ k_CheckCrcMode_FirstPass; // for filters
+ // k_CheckCrcMode_Never; // for debug
+ // k_CheckCrcMode_Always; // for debug
+ if (fileData)
+ {
+ encoder.UseRealData_Enc = true;
+ encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
+ }
+ }
UInt32 crc = 0;
if (fileData)
@@ -1260,22 +1898,41 @@ static HRESULT MethodBench(
{
CEncoderInfo &encoder = encoders[i];
encoder._method = method;
+ encoder.generateDictBits = generateDictBits;
encoder._uncompressedDataSize = uncompressedDataSize;
encoder.kBufferSize = uncompressedDataSize;
encoder.fileData = fileData;
encoder.crc = crc;
-
- RINOK(encoders[i].Init(method, generateDictBits, &rg));
}
CBenchProgressStatus status;
status.Res = S_OK;
status.EncodeMode = true;
+ #ifndef Z7_ST
+ CBenchThreadsFlusher encoderFlusher;
+ if (mtEncMode)
+ {
+ WRes wres = encoderFlusher.Common.StartEvent.Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ encoderFlusher.NumThreads = numEncoderThreads;
+ encoderFlusher.EncodersSpec = &encodersSpec;
+ encoderFlusher.NeedClose = true;
+ }
+ #endif
+
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
- encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands);
+ encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands);
+ // encoder.NumIterations = 3;
+ encoder.Salt = g_CrcTable[i & 0xFF];
+ encoder.Salt ^= (g_CrcTable[(i >> 8) & 0xFF] << 3);
+ // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread
+ // printf(" %8x", encoder.Salt);
+
+ encoder.KeySize = benchProps->KeySize;
for (int j = 0; j < 2; j++)
{
@@ -1290,32 +1947,53 @@ static HRESULT MethodBench(
CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
bpi->Callback = callback;
bpi->BenchInfo.NumIterations = numEncoderThreads;
- bpi->SetStartTime();
}
- #ifndef _7ZIP_ST
- if (numEncoderThreads > 1)
+ #ifndef Z7_ST
+ if (mtEncMode)
{
#ifdef USE_ALLOCA
encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
#endif
+ encoder.Common = &encoderFlusher.Common;
+ encoder.IsGlobalMtMode = numEncoderThreads > 1;
RINOK(encoder.CreateEncoderThread())
}
- else
#endif
+ }
+
+ if (printCallback)
+ {
+ RINOK(printCallback->CheckBreak())
+ }
+
+ #ifndef Z7_ST
+ if (mtEncMode)
+ {
+ for (i = 0; i < numEncoderThreads; i++)
{
- RINOK(encoder.Encode());
+ CEncoderInfo &encoder = encoders[i];
+ const WRes wres = encoder.ReadyEvent.Lock();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ RINOK(encoder.Results[0])
}
+
+ CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0];
+ bpi->SetStartTime();
+
+ const WRes wres = encoderFlusher.StartAndWait();
+ if (status.Res == 0 && wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
-
- #ifndef _7ZIP_ST
- if (numEncoderThreads > 1)
- for (i = 0; i < numEncoderThreads; i++)
- encoders[i].thread[0].Wait();
+ else
#endif
+ {
+ RINOK(encoders[0].Encode())
+ }
- RINOK(status.Res);
+ RINOK(status.Res)
CBenchInfo info;
@@ -1326,26 +2004,47 @@ static HRESULT MethodBench(
for (i = 0; i < numEncoderThreads; i++)
{
- CEncoderInfo &encoder = encoders[i];
+ const CEncoderInfo &encoder = encoders[i];
info.UnpackSize += encoder.kBufferSize;
info.PackSize += encoder.compressedSize;
+ // printf("\n%7d\n", encoder.compressedSize);
}
- RINOK(callback->SetEncodeResult(info, true));
+ RINOK(callback->SetEncodeResult(info, true))
+
+
+ // ---------- Decode ----------
+
status.Res = S_OK;
status.EncodeMode = false;
- UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
+ const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
+ #ifndef Z7_ST
+ const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity();
+ #endif
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
+ /*
+ #ifndef Z7_ST
+ // encoder.affinityMode = *affinityMode;
+ if (encoder.NumEncoderInternalThreads != 1)
+ encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads;
+ #endif
+ */
+
+
if (i == 0)
{
- encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands);
+ encoder.NumIterations = GetNumIterations(
+ benchProps->GetNumCommands_Dec(
+ encoder.compressedSize,
+ encoder.kBufferSize),
+ complexInCommands);
CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
bpi->Callback = callback;
bpi->BenchInfo.NumIterations = numDecoderThreads;
@@ -1354,50 +2053,61 @@ static HRESULT MethodBench(
else
encoder.NumIterations = encoders[0].NumIterations;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
{
int numSubThreads = method.Get_NumThreads();
- encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : numSubThreads;
+ encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads;
}
- if (numDecoderThreads > 1)
+ if (mtDecoderMode)
{
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
- HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
+ const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
#ifdef USE_ALLOCA
, ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF
#endif
);
- RINOK(res);
+ RINOK(res)
}
}
else
#endif
{
- RINOK(encoder.Decode(0));
+ RINOK(encoder.Decode(0))
}
}
- #ifndef _7ZIP_ST
- HRESULT res = S_OK;
- if (numDecoderThreads > 1)
+ #ifndef Z7_ST
+ if (mtDecoderMode)
+ {
+ WRes wres = 0;
+ HRESULT res = S_OK;
for (i = 0; i < numEncoderThreads; i++)
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
CEncoderInfo &encoder = encoders[i];
- encoder.thread[j].Wait();
- if (encoder.Results[j] != S_OK)
- res = encoder.Results[j];
+ const WRes wres2 = encoder.thread[j].
+ // Wait(); // later we can get thread times from thread in UNDER_CE
+ Wait_Close();
+ if (wres == 0 && wres2 != 0)
+ wres = wres2;
+ const HRESULT res2 = encoder.Results[j];
+ if (res == 0 && res2 != 0)
+ res = res2;
}
- RINOK(res);
- #endif
-
- RINOK(status.Res);
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ RINOK(res)
+ }
+ #endif // Z7_ST
+
+ RINOK(status.Res)
encoders[0].progressInfoSpec[0]->SetFinishTime(info);
-
- #ifndef _7ZIP_ST
+
+ /*
+ #ifndef Z7_ST
#ifdef UNDER_CE
- if (numDecoderThreads > 1)
+ if (mtDecoderMode)
for (i = 0; i < numEncoderThreads; i++)
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
@@ -1407,6 +2117,7 @@ static HRESULT MethodBench(
}
#endif
#endif
+ */
info.UnpackSize = 0;
info.PackSize = 0;
@@ -1414,21 +2125,41 @@ static HRESULT MethodBench(
for (i = 0; i < numEncoderThreads; i++)
{
- CEncoderInfo &encoder = encoders[i];
+ const CEncoderInfo &encoder = encoders[i];
info.UnpackSize += encoder.kBufferSize;
info.PackSize += encoder.compressedSize;
}
- RINOK(callback->SetDecodeResult(info, false));
- RINOK(callback->SetDecodeResult(info, true));
+ // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ??
+ RINOK(callback->SetDecodeResult(info, true))
return S_OK;
}
-static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
+
+static inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog)
+{
+ /*
+ if (dictSizeLog < 32)
+ return (UInt32)1 << dictSizeLog;
+ else
+ return (UInt32)(Int32)-1;
+ */
+ return (UInt64)1 << dictSizeLog;
+}
+
+
+// it's limit of current LZMA implementation that can be changed later
+#define kLzmaMaxDictSize ((UInt32)15 << 28)
+
+static inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict)
{
- UInt32 hs = dictionary - 1;
+ if (dict == 0)
+ dict = 1;
+ if (dict > kLzmaMaxDictSize)
+ dict = kLzmaMaxDictSize;
+ UInt32 hs = (UInt32)dict - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
@@ -1438,53 +2169,158 @@ static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
if (hs > (1 << 24))
hs >>= 1;
hs++;
- return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 +
+ hs += (1 << 16);
+
+ const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
+ UInt64 blockSize = (UInt64)dict + (1 << 16)
+ + (multiThread ? (1 << 20) : 0);
+ blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
+ if (blockSize >= kBlockSizeMax)
+ blockSize = kBlockSizeMax;
+
+ UInt64 son = (UInt64)dict;
+ if (btMode)
+ son *= 2;
+ const UInt64 v = (hs + son) * 4 + blockSize +
(1 << 20) + (multiThread ? (6 << 20) : 0);
+
+ // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20));
+ // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20));
+ return v;
}
-UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench)
+
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench)
{
- const UInt32 kBufferSize = dictionary;
- const UInt32 kCompressedBufferSize = kBufferSize; // / 2;
- bool lzmaMt = (totalBench || numThreads > 1);
+ const size_t kBufferSize = (size_t)dictionary + kAdditionalSize;
+ const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2;
+ if (level < 0)
+ level = 5;
+ const int algo = (level < 5 ? 0 : 1);
+ const int btMode = (algo == 0 ? 0 : 1);
+
UInt32 numBigThreads = numThreads;
- if (!totalBench && lzmaMt)
- numBigThreads /= 2;
+ bool lzmaMt = (totalBench || (numThreads > 1 && btMode));
+ if (btMode)
+ {
+ if (!totalBench && lzmaMt)
+ numBigThreads /= 2;
+ }
return ((UInt64)kBufferSize + kCompressedBufferSize +
- GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads;
+ GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads;
}
-static HRESULT CrcBig(const void *data, UInt32 size, UInt64 numIterations,
+static UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary)
+{
+ // dictionary += (dictionary >> 9); // for page tables (virtual memory)
+ return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20);
+}
+
+
+// ---------- CRC and HASH ----------
+
+struct CCrcInfo_Base
+{
+ CMidAlignedBuffer Buffer;
+ const Byte *Data;
+ size_t Size;
+ bool CreateLocalBuf;
+ UInt32 CheckSum_Res;
+
+ CCrcInfo_Base(): CreateLocalBuf(true), CheckSum_Res(0) {}
+
+ HRESULT Generate(const Byte *data, size_t size);
+ HRESULT CrcProcess(UInt64 numIterations,
+ const UInt32 *checkSum, IHasher *hf,
+ IBenchPrintCallback *callback);
+};
+
+
+HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size)
+{
+ Size = size;
+ Data = data;
+ if (!data || CreateLocalBuf)
+ {
+ ALLOC_WITH_HRESULT(&Buffer, size)
+ Data = Buffer;
+ }
+ if (!data)
+ RandGen(Buffer, size);
+ else if (CreateLocalBuf && size != 0)
+ memcpy(Buffer, data, size);
+ return S_OK;
+}
+
+
+HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
const UInt32 *checkSum, IHasher *hf,
IBenchPrintCallback *callback)
{
+ MY_ALIGN(16)
Byte hash[64];
- UInt64 i;
- for (i = 0; i < sizeof(hash); i++)
- hash[i] = 0;
- for (i = 0; i < numIterations; i++)
+ memset(hash, 0, sizeof(hash));
+
+ CheckSum_Res = 0;
+
+ const UInt32 hashSize = hf->GetDigestSize();
+ if (hashSize > sizeof(hash))
+ return S_FALSE;
+
+ const Byte *buf = Data;
+ const size_t size = Size;
+ UInt32 checkSum_Prev = 0;
+
+ UInt64 prev = 0;
+ UInt64 cur = 0;
+
+ for (UInt64 i = 0; i < numIterations; i++)
{
- if (callback && (i & 0xFF) == 0)
+ hf->Init();
+ size_t pos = 0;
+ do
{
- RINOK(callback->CheckBreak());
+ const size_t rem = size - pos;
+ const UInt32 kStep = ((UInt32)1 << 31);
+ const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
+ hf->Update(buf + pos, curSize);
+ pos += curSize;
}
- hf->Init();
- hf->Update(data, size);
+ while (pos != size);
+
hf->Final(hash);
- UInt32 hashSize = hf->GetDigestSize();
- if (hashSize > sizeof(hash))
- return S_FALSE;
UInt32 sum = 0;
for (UInt32 j = 0; j < hashSize; j += 4)
- sum ^= GetUi32(hash + j);
- if (checkSum && sum != *checkSum)
{
- return S_FALSE;
+ sum = rotlFixed(sum, 11);
+ sum += GetUi32(hash + j);
+ }
+ if (checkSum)
+ {
+ if (sum != *checkSum)
+ return S_FALSE;
+ }
+ else
+ {
+ checkSum_Prev = sum;
+ checkSum = &checkSum_Prev;
+ }
+ if (callback)
+ {
+ cur += size;
+ if (cur - prev >= ((UInt32)1 << 30))
+ {
+ prev = cur;
+ RINOK(callback->CheckBreak())
+ }
}
}
+ CheckSum_Res = checkSum_Prev;
return S_OK;
}
+extern
+UInt32 g_BenchCpuFreqTemp; // we need non-static variavble to disable compiler optimization
UInt32 g_BenchCpuFreqTemp = 1;
#define YY1 sum += val; sum ^= val;
@@ -1507,24 +2343,29 @@ static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
EXTERN_C_END
-#ifndef _7ZIP_ST
+#ifndef Z7_ST
-struct CFreqInfo
+struct CBaseThreadInfo
{
NWindows::CThread Thread;
IBenchPrintCallback *Callback;
HRESULT CallbackRes;
- UInt32 ValRes;
- UInt32 Size;
- UInt64 NumIterations;
- void Wait()
+ WRes Wait_If_Created()
{
- Thread.Wait();
- Thread.Close();
+ if (!Thread.IsCreated())
+ return 0;
+ return Thread.Wait_Close();
}
};
+struct CFreqInfo: public CBaseThreadInfo
+{
+ UInt32 ValRes;
+ UInt32 Size;
+ UInt64 NumIterations;
+};
+
static THREAD_FUNC_DECL FreqThreadFunction(void *param)
{
CFreqInfo *p = (CFreqInfo *)param;
@@ -1532,13 +2373,16 @@ static THREAD_FUNC_DECL FreqThreadFunction(void *param)
UInt32 sum = g_BenchCpuFreqTemp;
for (UInt64 k = p->NumIterations; k > 0; k--)
{
- p->CallbackRes = p->Callback->CheckBreak();
- if (p->CallbackRes != S_OK)
- return 0;
+ if (p->Callback)
+ {
+ p->CallbackRes = p->Callback->CheckBreak();
+ if (p->CallbackRes != S_OK)
+ break;
+ }
sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp);
}
p->ValRes = sum;
- return 0;
+ return THREAD_FUNC_RET_ZERO;
}
struct CFreqThreads
@@ -1546,13 +2390,21 @@ struct CFreqThreads
CFreqInfo *Items;
UInt32 NumThreads;
- CFreqThreads(): Items(0), NumThreads(0) {}
- void WaitAll()
+ CFreqThreads(): Items(NULL), NumThreads(0) {}
+
+ WRes WaitAll()
{
+ WRes wres = 0;
for (UInt32 i = 0; i < NumThreads; i++)
- Items[i].Wait();
+ {
+ WRes wres2 = Items[i].Wait_If_Created();
+ if (wres == 0 && wres2 != 0)
+ wres = wres2;
+ }
NumThreads = 0;
+ return wres;
}
+
~CFreqThreads()
{
WaitAll();
@@ -1560,30 +2412,95 @@ struct CFreqThreads
}
};
-struct CCrcInfo
-{
- NWindows::CThread Thread;
- IBenchPrintCallback *Callback;
- HRESULT CallbackRes;
+static THREAD_FUNC_DECL CrcThreadFunction(void *param);
+
+struct CCrcInfo: public CBaseThreadInfo
+{
const Byte *Data;
- UInt32 Size;
+ size_t Size;
UInt64 NumIterations;
bool CheckSumDefined;
UInt32 CheckSum;
CMyComPtr<IHasher> Hasher;
HRESULT Res;
+ UInt32 CheckSum_Res;
+
+ #ifndef Z7_ST
+ NSynchronization::CManualResetEvent ReadyEvent;
+ UInt32 ThreadIndex;
+ CBenchSyncCommon *Common;
+ CAffinityMode AffinityMode;
+ #endif
+
+ // we want to call CCrcInfo_Base::Buffer.Free() in main thread.
+ // so we uses non-local CCrcInfo_Base.
+ CCrcInfo_Base crcib;
+
+ HRESULT CreateThread()
+ {
+ WRes res = 0;
+ if (!ReadyEvent.IsCreated())
+ res = ReadyEvent.Create();
+ if (res == 0)
+ res = AffinityMode.CreateThread_WithAffinity(Thread, CrcThreadFunction, this,
+ ThreadIndex);
+ return HRESULT_FROM_WIN32(res);
+ }
#ifdef USE_ALLOCA
size_t AllocaSize;
#endif
- void Wait()
+ void Process();
+
+ CCrcInfo(): Res(E_FAIL) {}
+};
+
+static const bool k_Crc_CreateLocalBuf_For_File = true; // for total BW test
+// static const bool k_Crc_CreateLocalBuf_For_File = false; // for shared memory read test
+
+void CCrcInfo::Process()
+{
+ crcib.CreateLocalBuf = k_Crc_CreateLocalBuf_For_File;
+ // we can use additional Generate() passes to reduce some time effects for new page allocation
+ // for (unsigned y = 0; y < 10; y++)
+ Res = crcib.Generate(Data, Size);
+
+ // if (Common)
{
- Thread.Wait();
- Thread.Close();
+ WRes wres = ReadyEvent.Set();
+ if (wres != 0)
+ {
+ if (Res == 0)
+ Res = HRESULT_FROM_WIN32(wres);
+ return;
+ }
+ if (Res != 0)
+ return;
+
+ wres = Common->StartEvent.Lock();
+
+ if (wres != 0)
+ {
+ Res = HRESULT_FROM_WIN32(wres);
+ return;
+ }
+ if (Common->ExitMode)
+ return;
}
-};
+
+ Res = crcib.CrcProcess(NumIterations,
+ CheckSumDefined ? &CheckSum : NULL, Hasher,
+ Callback);
+ CheckSum_Res = crcib.CheckSum_Res;
+ /*
+ We don't want to include the time of slow CCrcInfo_Base::Buffer.Free()
+ to time of benchmark. So we don't free Buffer here
+ */
+ // crcib.Buffer.Free();
+}
+
static THREAD_FUNC_DECL CrcThreadFunction(void *param)
{
@@ -1592,73 +2509,87 @@ static THREAD_FUNC_DECL CrcThreadFunction(void *param)
#ifdef USE_ALLOCA
alloca(p->AllocaSize);
#endif
-
- p->Res = CrcBig(p->Data, p->Size, p->NumIterations,
- p->CheckSumDefined ? &p->CheckSum : NULL, p->Hasher,
- p->Callback);
- return 0;
+ p->Process();
+ return THREAD_FUNC_RET_ZERO;
}
+
struct CCrcThreads
{
CCrcInfo *Items;
- UInt32 NumThreads;
+ unsigned NumThreads;
+ CBenchSyncCommon Common;
+ bool NeedClose;
+
+ CCrcThreads(): Items(NULL), NumThreads(0), NeedClose(false) {}
+
+ WRes StartAndWait(bool exitMode = false);
- CCrcThreads(): Items(0), NumThreads(0) {}
- void WaitAll()
- {
- for (UInt32 i = 0; i < NumThreads; i++)
- Items[i].Wait();
- NumThreads = 0;
- }
~CCrcThreads()
{
- WaitAll();
+ StartAndWait(true);
delete []Items;
}
};
-#endif
-static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
+WRes CCrcThreads::StartAndWait(bool exitMode)
{
- UInt32 crc = CRC_INIT_VAL;;
- for (UInt32 i = 0; i < size; i++)
- crc = CRC_UPDATE_BYTE(crc, buf[i]);
- return CRC_GET_DIGEST(crc);
+ if (!NeedClose)
+ return 0;
+
+ Common.ExitMode = exitMode;
+ WRes wres = Common.StartEvent.Set();
+
+ for (unsigned i = 0; i < NumThreads; i++)
+ {
+ WRes wres2 = Items[i].Wait_If_Created();
+ if (wres == 0 && wres2 != 0)
+ wres = wres2;
+ }
+ NumThreads = 0;
+ NeedClose = false;
+ return wres;
}
-static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+#endif
+
+
+static UInt32 CrcCalc1(const Byte *buf, size_t size)
{
- for (UInt32 i = 0; i < size; i++)
- buf[i] = (Byte)RG.GetRnd();
+ UInt32 crc = CRC_INIT_VAL;
+ for (size_t i = 0; i < size; i++)
+ crc = CRC_UPDATE_BYTE(crc, buf[i]);
+ return CRC_GET_DIGEST(crc);
}
-static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+/*
+static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG)
{
RandGen(buf, size, RG);
return CrcCalc1(buf, size);
}
+*/
-bool CrcInternalTest()
+static bool CrcInternalTest()
{
- CBenchBuffer buffer;
- const UInt32 kBufferSize0 = (1 << 8);
- const UInt32 kBufferSize1 = (1 << 10);
- const UInt32 kCheckSize = (1 << 5);
- if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
+ CAlignedBuffer buffer;
+ const size_t kBufferSize0 = (1 << 8);
+ const size_t kBufferSize1 = (1 << 10);
+ const unsigned kCheckSize = (1 << 5);
+ buffer.Alloc(kBufferSize0 + kBufferSize1);
+ if (!buffer.IsAllocated())
return false;
- Byte *buf = buffer.Buffer;
- UInt32 i;
+ Byte *buf = (Byte *)buffer;
+ size_t i;
for (i = 0; i < kBufferSize0; i++)
buf[i] = (Byte)i;
UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
if (crc1 != 0x29058C73)
return false;
- CBaseRandomGenerator RG;
- RandGen(buf + kBufferSize0, kBufferSize1, RG);
+ RandGen(buf + kBufferSize0, kBufferSize1);
for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
- for (UInt32 j = 0; j < kCheckSize; j++)
+ for (unsigned j = 0; j < kCheckSize; j++)
if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
return false;
return true;
@@ -1668,15 +2599,29 @@ struct CBenchMethod
{
unsigned Weight;
unsigned DictBits;
- UInt32 EncComplex;
- UInt32 DecComplexCompr;
- UInt32 DecComplexUnc;
+ Int32 EncComplex;
+ Int32 DecComplexCompr;
+ Int32 DecComplexUnc;
const char *Name;
+ // unsigned KeySize;
};
+// #define USE_SW_CMPLX
+
+#ifdef USE_SW_CMPLX
+#define CMPLX(x) ((x) * 1000)
+#else
+#define CMPLX(x) (x)
+#endif
+
static const CBenchMethod g_Bench[] =
{
- { 40, 17, 357, 145, 20, "LZMA:x1" },
+ // { 40, 17, 357, 145, 20, "LZMA:x1" },
+ // { 20, 18, 360, 145, 20, "LZMA2:x1:mt2" },
+
+ { 20, 18, 360, 145, 20, "LZMA:x1" },
+ { 20, 22, 600, 145, 20, "LZMA:x3" },
+
{ 80, 24, 1220, 145, 20, "LZMA:x5:mt1" },
{ 80, 24, 1220, 145, 20, "LZMA:x5:mt2" },
@@ -1690,14 +2635,46 @@ static const CBenchMethod g_Bench[] =
{ 10, 19, 815, 122, 122, "BZip2:x5:mt2" },
{ 10, 19, 2530, 122, 122, "BZip2:x7" },
+ // { 10, 18, 1010, 0, 1150, "PPMDZip:x1" },
{ 10, 18, 1010, 0, 1150, "PPMD:x1" },
+ // { 10, 22, 1655, 0, 1830, "PPMDZip:x5" },
{ 10, 22, 1655, 0, 1830, "PPMD:x5" },
- { 2, 0, 6, 0, 6, "Delta:4" },
- { 2, 0, 4, 0, 4, "BCJ" },
+ // { 2, 0, -16, 0, -16, "Swap2" },
+ { 2, 0, -16, 0, -16, "Swap4" },
+ // { 2, 0, 3, 0, 4, "Delta:1" },
+ // { 2, 0, 3, 0, 4, "Delta:2" },
+ // { 2, 0, 3, 0, 4, "Delta:3" },
+ { 2, 0, 3, 0, 4, "Delta:4" },
+ // { 2, 0, 3, 0, 4, "Delta:8" },
+ // { 2, 0, 3, 0, 4, "Delta:32" },
+
+ { 2, 0, 2, 0, 2, "BCJ" },
+ { 2, 0, 1, 0, 1, "ARM64" },
+
+ // { 10, 0, 18, 0, 18, "AES128CBC:1" },
+ // { 10, 0, 21, 0, 21, "AES192CBC:1" },
{ 10, 0, 24, 0, 24, "AES256CBC:1" },
- { 2, 0, 8, 0, 2, "AES256CBC:2" }
+
+ // { 10, 0, 18, 0, 18, "AES128CTR:1" },
+ // { 10, 0, 21, 0, 21, "AES192CTR:1" },
+ // { 10, 0, 24, 0, 24, "AES256CTR:1" },
+ // { 2, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:2" },
+ // { 2, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:2" },
+ { 2, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:2" },
+
+ // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:2" },
+ // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" },
+ // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" },
+
+ // { 1, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:3" },
+ // { 1, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:3" },
+ { 1, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:3" }
+
+ // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:3" },
+ // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:3" },
+ // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:3" },
};
struct CBenchHash
@@ -1708,36 +2685,27 @@ struct CBenchHash
const char *Name;
};
-static const CBenchHash g_Hash[] =
-{
- { 1, 1820, 0x8F8FEDAB, "CRC32:1" },
- { 10, 558, 0x8F8FEDAB, "CRC32:4" },
- { 10, 339, 0x8F8FEDAB, "CRC32:8" },
- { 10, 512, 0xDF1C17CC, "CRC64" },
- { 10, 5100, 0x2D79FF2E, "SHA256" },
- { 10, 2340, 0x4C25132B, "SHA1" },
- { 2, 5500, 0xE084E913, "BLAKE2sp" }
-};
+// #define ARM_CRC_MUL 100
+#define ARM_CRC_MUL 1
-struct CTotalBenchRes
-{
- // UInt64 NumIterations1; // for Usage
- UInt64 NumIterations2; // for Rating / RPU
+#define k_Hash_Complex_Mult 256
- UInt64 Rating;
- UInt64 Usage;
- UInt64 RPU;
+static const CBenchHash g_Hash[] =
+{
+ // { 1, 1820, 0x21e207bb, "CRC32:1" },
+ // { 10, 558, 0x21e207bb, "CRC32:4" },
+ { 20, 339, 0x21e207bb, "CRC32:8" } ,
+ { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
+ { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
+ { 10, 512, 0x41b901d1, "CRC64" },
- void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; }
-
- void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
- {
- Rating = (r1.Rating + r2.Rating);
- Usage = (r1.Usage + r2.Usage);
- RPU = (r1.RPU + r2.RPU);
- // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
- NumIterations2 = (r1.NumIterations2 + r2.NumIterations2);
- }
+ { 10, 5100, 0x7913ba03, "SHA256:1" },
+ { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
+
+ { 10, 2340, 0xff769021, "SHA1:1" },
+ { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
+
+ { 2, 5500, 0x85189d02, "BLAKE2sp" }
};
static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size)
@@ -1754,9 +2722,11 @@ static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size)
unsigned len = (unsigned)strlen(s + startPos);
if (size > len)
{
- startPos -= (size - len);
- if (startPos < 0)
+ size -= len;
+ if (startPos < size)
startPos = 0;
+ else
+ startPos -= size;
}
f.Print(s + startPos);
}
@@ -1769,6 +2739,8 @@ static const unsigned kFieldSize_RU = 6;
static const unsigned kFieldSize_Rating = 6;
static const unsigned kFieldSize_EU = 5;
static const unsigned kFieldSize_Effec = 5;
+static const unsigned kFieldSize_CrcSpeed = 8;
+
static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating;
static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec;
@@ -1782,7 +2754,10 @@ static void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size)
static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size)
{
- PrintNumber(f, (val * 100 + divider / 2) / divider, size);
+ UInt64 v = 0;
+ if (divider != 0)
+ v = (val * 100 + divider / 2) / divider;
+ PrintNumber(f, v, size);
}
static void PrintChars(IBenchPrintCallback &f, char c, unsigned size)
@@ -1798,9 +2773,14 @@ static void PrintSpaces(IBenchPrintCallback &f, unsigned size)
PrintChars(f, ' ', size);
}
+static void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size)
+{
+ PrintNumber(f, Benchmark_GetUsage_Percents(usage), size);
+}
+
static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq)
{
- PrintNumber(f, (usage + 5000) / 10000, kFieldSize_Usage);
+ PrintUsage(f, usage, kFieldSize_Usage);
PrintRating(f, rpu, kFieldSize_RU);
PrintRating(f, rating, kFieldSize_Rating);
if (showFreq)
@@ -1809,15 +2789,39 @@ static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt6
PrintSpaces(f, kFieldSize_EUAndEffec);
else
{
- UInt64 ddd = cpuFreq * usage / 100;
- if (ddd == 0)
- ddd = 1;
- PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU);
+ PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU);
PrintPercents(f, rating, cpuFreq, kFieldSize_Effec);
}
}
}
+
+void CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info)
+{
+ Speed = info.GetUnpackSizeSpeed();
+ Usage = info.GetUsage();
+ RPU = info.GetRatingPerUsage(Rating);
+}
+
+void CTotalBenchRes::Mult_For_Weight(unsigned weight)
+{
+ NumIterations2 *= weight;
+ RPU *= weight;
+ Rating *= weight;
+ Usage *= weight;
+ Speed *= weight;
+}
+
+void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r)
+{
+ Rating += r.Rating;
+ Usage += r.Usage;
+ RPU += r.RPU;
+ Speed += r.Speed;
+ // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
+ NumIterations2 += r.NumIterations2;
+}
+
static void PrintResults(IBenchPrintCallback *f,
const CBenchInfo &info,
unsigned weight,
@@ -1825,39 +2829,126 @@ static void PrintResults(IBenchPrintCallback *f,
bool showFreq, UInt64 cpuFreq,
CTotalBenchRes *res)
{
- UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations);
+ CTotalBenchRes t;
+ t.Rating = rating;
+ t.NumIterations2 = 1;
+ t.Generate_From_BenchInfo(info);
+
if (f)
{
- if (speed != 0)
- PrintNumber(*f, speed / 1024, kFieldSize_Speed);
+ if (t.Speed != 0)
+ PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed);
else
PrintSpaces(*f, 1 + kFieldSize_Speed);
}
- UInt64 usage = info.GetUsage();
- UInt64 rpu = info.GetRatingPerUsage(rating);
if (f)
{
- PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq);
+ PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq);
}
if (res)
{
// res->NumIterations1++;
- res->NumIterations2 += weight;
- res->RPU += (rpu * weight);
- res->Rating += (rating * weight);
- res->Usage += (usage * weight);
+ t.Mult_For_Weight(weight);
+ res->Update_With_Res(t);
}
}
-static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res)
+static void PrintTotals(IBenchPrintCallback &f,
+ bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res)
{
- PrintSpaces(f, 1 + kFieldSize_Speed);
+ const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1;
+ const UInt64 speed = res.Speed / numIterations2;
+ if (showSpeed && speed != 0)
+ PrintNumber(f, speed / 1024, kFieldSize_Speed);
+ else
+ PrintSpaces(f, 1 + kFieldSize_Speed);
+
+ // PrintSpaces(f, 1 + kFieldSize_Speed);
// UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1;
- UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1;
PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
}
+
+static void PrintHex(AString &s, UInt64 v)
+{
+ char temp[32];
+ ConvertUInt64ToHex(v, temp);
+ s += temp;
+}
+
+AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
+{
+ AString s;
+ // s.Add_UInt32(ti.numProcessThreads);
+ unsigned numSysThreads = ti.GetNumSystemThreads();
+ if (ti.GetNumProcessThreads() != numSysThreads)
+ {
+ // if (ti.numProcessThreads != ti.numSysThreads)
+ {
+ s += " / ";
+ s.Add_UInt32(numSysThreads);
+ }
+ s += " : ";
+ #ifdef _WIN32
+ PrintHex(s, ti.processAffinityMask);
+ s += " / ";
+ PrintHex(s, ti.systemAffinityMask);
+ #else
+ unsigned i = (numSysThreads + 3) & ~(unsigned)3;
+ if (i == 0)
+ i = 4;
+ for (; i >= 4; )
+ {
+ i -= 4;
+ unsigned val = 0;
+ for (unsigned k = 0; k < 4; k++)
+ {
+ const unsigned bit = (ti.IsCpuSet(i + k) ? 1 : 0);
+ val += (bit << k);
+ }
+ PrintHex(s, val);
+ }
+ #endif
+ }
+ return s;
+}
+
+
+#ifdef Z7_LARGE_PAGES
+
+#ifdef _WIN32
+extern bool g_LargePagesMode;
+extern "C"
+{
+ extern SIZE_T g_LargePageSize;
+}
+#endif
+
+void Add_LargePages_String(AString &s)
+{
+ #ifdef _WIN32
+ if (g_LargePagesMode || g_LargePageSize != 0)
+ {
+ s.Add_OptSpaced("(LP-");
+ PrintSize_KMGT_Or_Hex(s, g_LargePageSize);
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (CPU_IsSupported_PageGB())
+ s += "-1G";
+ #endif
+ if (!g_LargePagesMode)
+ s += "-NA";
+ s += ")";
+ }
+ #else
+ s += "";
+ #endif
+}
+
+#endif
+
+
+
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
{
@@ -1867,36 +2958,51 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
PrintNumber(f, (size >> 20), 6);
else
f.Print(" ?");
- f.Print(" MB, # ");
+ f.Print(" MB");
+
+ #ifdef Z7_LARGE_PAGES
+ {
+ AString s;
+ Add_LargePages_String(s);
+ f.Print(s);
+ }
+ #endif
+
+ f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
- f.NewLine();
}
-struct CBenchCallbackToPrint: public IBenchCallback
-{
- CBenchProps BenchProps;
- CTotalBenchRes EncodeRes;
- CTotalBenchRes DecodeRes;
- IBenchPrintCallback *_file;
- UInt32 DictSize;
- bool Use2Columns;
- unsigned NameFieldSize;
+struct CBenchCallbackToPrint Z7_final: public IBenchCallback
+{
+ bool NeedPrint;
+ bool Use2Columns;
bool ShowFreq;
- UInt64 CpuFreq;
+ unsigned NameFieldSize;
unsigned EncodeWeight;
unsigned DecodeWeight;
+ UInt64 CpuFreq;
+ UInt64 DictSize;
+
+ IBenchPrintCallback *_file;
+ CBenchProps BenchProps;
+ CTotalBenchRes EncodeRes;
+ CTotalBenchRes DecodeRes;
+
+ CBenchInfo BenchInfo_Results[2];
+
CBenchCallbackToPrint():
+ NeedPrint(true),
Use2Columns(false),
- NameFieldSize(0),
ShowFreq(false),
- CpuFreq(0),
+ NameFieldSize(0),
EncodeWeight(1),
- DecodeWeight(1)
+ DecodeWeight(1),
+ CpuFreq(0)
{}
void Init() { EncodeRes.Init(); DecodeRes.Init(); }
@@ -1904,8 +3010,8 @@ struct CBenchCallbackToPrint: public IBenchCallback
void NewLine();
HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
- HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
- HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
+ HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override;
+ HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override;
};
HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
@@ -1917,10 +3023,13 @@ HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
{
- RINOK(_file->CheckBreak());
+ RINOK(_file->CheckBreak())
+ if (final)
+ BenchInfo_Results[0] = info;
if (final)
+ if (NeedPrint)
{
- UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
+ const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
PrintResults(_file, info,
EncodeWeight, rating,
ShowFreq, CpuFreq, &EncodeRes);
@@ -1930,14 +3039,17 @@ HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool fina
return S_OK;
}
-static const char *kSep = " | ";
+static const char * const kSep = " | ";
HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
{
- RINOK(_file->CheckBreak());
+ RINOK(_file->CheckBreak())
if (final)
+ BenchInfo_Results[1] = info;
+ if (final)
+ if (NeedPrint)
{
- UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
+ const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
if (Use2Columns)
_file->Print(kSep);
else
@@ -1963,35 +3075,58 @@ void CBenchCallbackToPrint::NewLine()
_file->NewLine();
}
-void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
+static void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
{
f.Print(s);
- int numSpaces = size - MyStringLen(s);
+ int numSpaces = (int)size - (int)MyStringLen(s);
if (numSpaces > 0)
- PrintSpaces(f, numSpaces);
+ PrintSpaces(f, (unsigned)numSpaces);
}
-void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
+static void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
{
- int numSpaces = size - MyStringLen(s);
+ int numSpaces = (int)size - (int)MyStringLen(s);
if (numSpaces > 0)
- PrintSpaces(f, numSpaces);
+ PrintSpaces(f, (unsigned)numSpaces);
f.Print(s);
}
+
+static bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name)
+{
+ UString wildc = GetUnicodeString(mask);
+ UString bname = GetUnicodeString(name);
+ wildc.MakeLower_Ascii();
+ bname.MakeLower_Ascii();
+ return DoesWildcardMatchName(wildc, bname);
+}
+
+
static HRESULT TotalBench(
DECL_EXTERNAL_CODECS_LOC_VARS
+ const COneMethodInfo &methodMask,
UInt64 complexInCommands,
+ #ifndef Z7_ST
UInt32 numThreads,
+ const CAffinityMode *affinityMode,
+ #endif
bool forceUnpackSize,
size_t unpackSize,
const Byte *fileData,
IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
{
const CBenchMethod &bench = g_Bench[i];
+ if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
+ continue;
PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
+ {
+ unsigned keySize = 32;
+ if (IsString1PrefixedByString2(bench.Name, "AES128")) keySize = 16;
+ else if (IsString1PrefixedByString2(bench.Name, "AES192")) keySize = 24;
+ callback->BenchProps.KeySize = keySize;
+ }
callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
callback->BenchProps.EncComplex = bench.EncComplex;
@@ -1999,7 +3134,7 @@ static HRESULT TotalBench(
COneMethodInfo method;
NCOM::CPropVariant propVariant;
propVariant = bench.Name;
- RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
+ RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
size_t unpackSize2 = unpackSize;
if (!forceUnpackSize && bench.DictBits == 0)
@@ -2008,10 +3143,13 @@ static HRESULT TotalBench(
callback->EncodeWeight = bench.Weight;
callback->DecodeWeight = bench.Weight;
- HRESULT res = MethodBench(
+ const HRESULT res = MethodBench(
EXTERNAL_CODECS_LOC_VARS
complexInCommands,
- false, numThreads, method,
+ #ifndef Z7_ST
+ false, numThreads, affinityMode,
+ #endif
+ method,
unpackSize2, fileData,
bench.DictBits,
printCallback, callback, &callback->BenchProps);
@@ -2025,7 +3163,7 @@ static HRESULT TotalBench(
}
else
{
- RINOK(res);
+ RINOK(res)
}
callback->NewLine();
@@ -2034,38 +3172,67 @@ static HRESULT TotalBench(
}
-static HRESULT FreqBench(
- UInt64 complexInCommands,
- UInt32 numThreads,
- IBenchPrintCallback *_file,
- bool showFreq,
- UInt64 specifiedFreq,
- UInt64 &cpuFreq,
- UInt32 &res)
+struct CFreqBench
+{
+ // in:
+ UInt64 complexInCommands;
+ UInt32 numThreads;
+ bool showFreq;
+ UInt64 specifiedFreq;
+
+ // out:
+ UInt64 CpuFreqRes;
+ UInt64 UsageRes;
+ UInt32 res;
+
+ CFreqBench()
+ {}
+
+ HRESULT FreqBench(IBenchPrintCallback *_file
+ #ifndef Z7_ST
+ , const CAffinityMode *affinityMode
+ #endif
+ );
+};
+
+
+HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file
+ #ifndef Z7_ST
+ , const CAffinityMode *affinityMode
+ #endif
+ )
{
res = 0;
- cpuFreq = 0;
+ CpuFreqRes = 0;
+ UsageRes = 0;
- UInt32 bufferSize = 1 << 20;
- UInt32 complexity = kNumFreqCommands;
if (numThreads == 0)
numThreads = 1;
- #ifdef _7ZIP_ST
+ #ifdef Z7_ST
numThreads = 1;
#endif
- UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
- UInt64 numIterations = complexInCommands / complexity / bsize;
- if (numIterations == 0)
+ const UInt32 complexity = kNumFreqCommands;
+ UInt64 numIterations = complexInCommands / complexity;
+ UInt32 numIterations2 = 1 << 30;
+ if (numIterations > numIterations2)
+ numIterations /= numIterations2;
+ else
+ {
+ numIterations2 = (UInt32)numIterations;
numIterations = 1;
+ }
CBenchInfoCalc progressInfoSpec;
- #ifndef _7ZIP_ST
- CFreqThreads threads;
- if (numThreads > 1)
+ #ifndef Z7_ST
+
+ bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity();
+
+ if (mtMode)
{
+ CFreqThreads threads;
threads.Items = new CFreqInfo[numThreads];
UInt32 i;
for (i = 0; i < numThreads; i++)
@@ -2074,19 +3241,25 @@ static HRESULT FreqBench(
info.Callback = _file;
info.CallbackRes = S_OK;
info.NumIterations = numIterations;
- info.Size = bufferSize;
+ info.Size = numIterations2;
}
progressInfoSpec.SetStartTime();
for (i = 0; i < numThreads; i++)
{
+ // Sleep(10);
CFreqInfo &info = threads.Items[i];
- RINOK(info.Thread.Create(FreqThreadFunction, &info));
- threads.NumThreads++;
+ WRes wres = affinityMode->CreateThread_WithAffinity(info.Thread, FreqThreadFunction, &info, i);
+ if (info.Thread.IsCreated())
+ threads.NumThreads++;
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
- threads.WaitAll();
+ WRes wres = threads.WaitAll();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
for (i = 0; i < numThreads; i++)
{
- RINOK(threads.Items[i].CallbackRes);
+ RINOK(threads.Items[i].CallbackRes)
}
}
else
@@ -2096,11 +3269,20 @@ static HRESULT FreqBench(
UInt32 sum = g_BenchCpuFreqTemp;
for (UInt64 k = numIterations; k > 0; k--)
{
- RINOK(_file->CheckBreak());
- sum = CountCpuFreq(sum, bufferSize, g_BenchCpuFreqTemp);
+ sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp);
+ if (_file)
+ {
+ RINOK(_file->CheckBreak())
+ }
}
res += sum;
}
+
+ if (res == 0x12345678)
+ if (_file)
+ {
+ RINOK(_file->CheckBreak())
+ }
CBenchInfo info;
progressInfoSpec.SetFinishTime(info);
@@ -2109,18 +3291,18 @@ static HRESULT FreqBench(
info.PackSize = 0;
info.NumIterations = 1;
+ const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity;
+ const UInt64 rating = info.GetSpeed(numCommands);
+ CpuFreqRes = rating / numThreads;
+ UsageRes = info.GetUsage();
+
if (_file)
{
- {
- UInt64 numCommands = (UInt64)numIterations * bufferSize * numThreads * complexity;
- UInt64 rating = info.GetSpeed(numCommands);
- cpuFreq = rating / numThreads;
- PrintResults(_file, info,
+ PrintResults(_file, info,
0, // weight
rating,
- showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL);
- }
- RINOK(_file->CheckBreak());
+ showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL);
+ RINOK(_file->CheckBreak())
}
return S_OK;
@@ -2131,23 +3313,32 @@ static HRESULT FreqBench(
static HRESULT CrcBench(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 complexInCommands,
- UInt32 numThreads, UInt32 bufferSize,
+ UInt32 numThreads,
+ const size_t bufferSize,
+ const Byte *fileData,
+
UInt64 &speed,
+ UInt64 &usage,
+
UInt32 complexity, unsigned benchWeight,
const UInt32 *checkSum,
const COneMethodInfo &method,
IBenchPrintCallback *_file,
+ #ifndef Z7_ST
+ const CAffinityMode *affinityMode,
+ #endif
+ bool showRating,
CTotalBenchRes *encodeRes,
bool showFreq, UInt64 cpuFreq)
{
if (numThreads == 0)
numThreads = 1;
- #ifdef _7ZIP_ST
+ #ifdef Z7_ST
numThreads = 1;
#endif
- AString methodName = method.MethodName;
+ const AString &methodName = method.MethodName;
// methodName.RemoveChar(L'-');
CMethodId hashID;
if (!FindHashMethod(
@@ -2155,98 +3346,131 @@ static HRESULT CrcBench(
methodName, hashID))
return E_NOTIMPL;
- CBenchBuffer buffer;
- size_t totalSize = (size_t)bufferSize * numThreads;
- if (totalSize / numThreads != bufferSize)
- return E_OUTOFMEMORY;
- if (!buffer.Alloc(totalSize))
- return E_OUTOFMEMORY;
+ /*
+ // if will generate random data in each thread, instead of global data
+ CMidAlignedBuffer buffer;
+ if (!fileData)
+ {
+ ALLOC_WITH_HRESULT(&buffer, bufferSize)
+ RandGen(buffer, bufferSize);
+ fileData = buffer;
+ }
+ */
- Byte *buf = buffer.Buffer;
- CBaseRandomGenerator RG;
- UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
- UInt64 numIterations = complexInCommands * 256 / complexity / bsize;
+ const size_t bsize = (bufferSize == 0 ? 1 : bufferSize);
+ UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize;
if (numIterations == 0)
numIterations = 1;
CBenchInfoCalc progressInfoSpec;
+ CBenchInfo info;
+
+ #ifndef Z7_ST
+ bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity();
- #ifndef _7ZIP_ST
- CCrcThreads threads;
- if (numThreads > 1)
+ if (mtEncMode)
{
+ CCrcThreads threads;
threads.Items = new CCrcInfo[numThreads];
-
+ {
+ WRes wres = threads.Common.StartEvent.Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ threads.NeedClose = true;
+ }
+
UInt32 i;
for (i = 0; i < numThreads; i++)
{
- CCrcInfo &info = threads.Items[i];
+ CCrcInfo &ci = threads.Items[i];
AString name;
- RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, info.Hasher));
- if (!info.Hasher)
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher))
+ if (!ci.Hasher)
return E_NOTIMPL;
CMyComPtr<ICompressSetCoderProperties> scp;
- info.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
if (scp)
{
- UInt64 reduceSize = 1;
- RINOK(method.SetCoderProps(scp, &reduceSize));
+ RINOK(method.SetCoderProps(scp))
}
- Byte *data = buf + (size_t)bufferSize * i;
- info.Callback = _file;
- info.Data = data;
- info.NumIterations = numIterations;
- info.Size = bufferSize;
- /* info.Crc = */ RandGenCrc(data, bufferSize, RG);
- info.CheckSumDefined = false;
+ ci.Callback = _file;
+ ci.Data = fileData;
+ ci.NumIterations = numIterations;
+ ci.Size = bufferSize;
+ ci.CheckSumDefined = false;
if (checkSum)
{
- info.CheckSum = *checkSum;
- info.CheckSumDefined = (checkSum && (i == 0));
+ ci.CheckSum = *checkSum;
+ ci.CheckSumDefined = true;
}
#ifdef USE_ALLOCA
- info.AllocaSize = (i * 16 * 21) & 0x7FF;
+ ci.AllocaSize = (i * 16 * 21) & 0x7FF;
#endif
}
- progressInfoSpec.SetStartTime();
+ for (i = 0; i < numThreads; i++)
+ {
+ CCrcInfo &ci = threads.Items[i];
+ ci.ThreadIndex = i;
+ ci.Common = &threads.Common;
+ ci.AffinityMode = *affinityMode;
+ HRESULT hres = ci.CreateThread();
+ if (ci.Thread.IsCreated())
+ threads.NumThreads++;
+ if (hres != 0)
+ return hres;
+ }
for (i = 0; i < numThreads; i++)
{
- CCrcInfo &info = threads.Items[i];
- RINOK(info.Thread.Create(CrcThreadFunction, &info));
- threads.NumThreads++;
+ CCrcInfo &ci = threads.Items[i];
+ WRes wres = ci.ReadyEvent.Lock();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ RINOK(ci.Res)
}
- threads.WaitAll();
+
+ progressInfoSpec.SetStartTime();
+
+ WRes wres = threads.StartAndWait();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+
+ progressInfoSpec.SetFinishTime(info);
+
for (i = 0; i < numThreads; i++)
{
- RINOK(threads.Items[i].Res);
+ RINOK(threads.Items[i].Res)
+ if (i != 0)
+ if (threads.Items[i].CheckSum_Res !=
+ threads.Items[i - 1].CheckSum_Res)
+ return S_FALSE;
}
}
else
#endif
{
- /* UInt32 crc = */ RandGenCrc(buf, bufferSize, RG);
- progressInfoSpec.SetStartTime();
CMyComPtr<IHasher> hasher;
AString name;
- RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher));
+ RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher))
if (!hasher)
return E_NOTIMPL;
CMyComPtr<ICompressSetCoderProperties> scp;
hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
if (scp)
{
- UInt64 reduceSize = 1;
- RINOK(method.SetCoderProps(scp, &reduceSize));
+ RINOK(method.SetCoderProps(scp))
}
- RINOK(CrcBig(buf, bufferSize, numIterations, checkSum, hasher, _file));
+ CCrcInfo_Base crcib;
+ crcib.CreateLocalBuf = false;
+ RINOK(crcib.Generate(fileData, bufferSize))
+ progressInfoSpec.SetStartTime();
+ RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file))
+ progressInfoSpec.SetFinishTime(info);
}
- CBenchInfo info;
- progressInfoSpec.SetFinishTime(info);
UInt64 unpSize = numIterations * bufferSize;
UInt64 unpSizeThreads = unpSize * numThreads;
@@ -2256,32 +3480,47 @@ static HRESULT CrcBench(
if (_file)
{
+ if (showRating)
{
- UInt64 numCommands = unpSizeThreads * complexity / 256;
- UInt64 rating = info.GetSpeed(numCommands);
+ UInt64 unpSizeThreads2 = unpSizeThreads;
+ if (unpSizeThreads2 == 0)
+ unpSizeThreads2 = numIterations * 1 * numThreads;
+ const UInt64 numCommands = unpSizeThreads2 * complexity / 256;
+ const UInt64 rating = info.GetSpeed(numCommands);
PrintResults(_file, info,
benchWeight, rating,
showFreq, cpuFreq, encodeRes);
}
- RINOK(_file->CheckBreak());
+ RINOK(_file->CheckBreak())
}
speed = info.GetSpeed(unpSizeThreads);
+ usage = info.GetUsage();
return S_OK;
}
+
+
static HRESULT TotalBench_Hash(
DECL_EXTERNAL_CODECS_LOC_VARS
+ const COneMethodInfo &methodMask,
UInt64 complexInCommands,
- UInt32 numThreads, UInt32 bufSize,
+ UInt32 numThreads,
+ size_t bufSize,
+ const Byte *fileData,
IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback,
+ #ifndef Z7_ST
+ const CAffinityMode *affinityMode,
+ #endif
CTotalBenchRes *encodeRes,
bool showFreq, UInt64 cpuFreq)
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
{
const CBenchHash &bench = g_Hash[i];
+ if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
+ continue;
PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
// callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
// callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
@@ -2290,24 +3529,31 @@ static HRESULT TotalBench_Hash(
COneMethodInfo method;
NCOM::CPropVariant propVariant;
propVariant = bench.Name;
- RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
+ RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
- UInt64 speed;
- HRESULT res = CrcBench(
+ UInt64 speed, usage;
+
+ const HRESULT res = CrcBench(
EXTERNAL_CODECS_LOC_VARS
complexInCommands,
- numThreads, bufSize,
- speed,
+ numThreads, bufSize, fileData,
+ speed, usage,
bench.Complex, bench.Weight,
- &bench.CheckSum, method,
- printCallback, encodeRes, showFreq, cpuFreq);
+ (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL,
+ method,
+ printCallback,
+ #ifndef Z7_ST
+ affinityMode,
+ #endif
+ true, // showRating
+ encodeRes, showFreq, cpuFreq);
if (res == E_NOTIMPL)
{
// callback->Print(" ---");
}
else
{
- RINOK(res);
+ RINOK(res)
}
callback->NewLine();
}
@@ -2317,7 +3563,8 @@ static HRESULT TotalBench_Hash(
struct CTempValues
{
UInt64 *Values;
- CTempValues(UInt32 num) { Values = new UInt64[num]; }
+ CTempValues(): Values(NULL) {}
+ void Alloc(UInt32 num) { Values = new UInt64[num]; }
~CTempValues() { delete []Values; }
};
@@ -2333,110 +3580,41 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
prop = result;
}
-static UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads)
-{
- if (i < 2)
- return i + 1;
- i -= 1;
- UInt32 num = (UInt32)(2 + (i & 1)) << (i >> 1);
- return (num <= numThreads) ? num : numThreads;
-}
static bool AreSameMethodNames(const char *fullName, const char *shortName)
{
- for (;;)
- {
- char c2 = *shortName++;
- if (c2 == 0)
- return true;
- char c1 = *fullName++;
- if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
- return false;
- }
+ return StringsAreEqualNoCase_Ascii(fullName, shortName);
}
-#ifdef MY_CPU_X86_OR_AMD64
-static void PrintCpuChars(AString &s, UInt32 v)
-{
- for (int j = 0; j < 4; j++)
- {
- Byte b = (Byte)(v & 0xFF);
- v >>= 8;
- if (b == 0)
- break;
- s += (char)b;
- }
-}
-static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
+static void Print_Usage_and_Threads(IBenchPrintCallback &f, UInt64 usage, UInt32 threads)
{
- s.Empty();
-
- UInt32 maxFunc2 = 0;
- UInt32 t[3];
-
- MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]);
-
- bool fullNameIsAvail = (maxFunc2 >= 0x80000004);
-
- if (!fullNameIsAvail)
- {
- for (int i = 0; i < 3; i++)
- PrintCpuChars(s, c.vendor[i]);
- }
- else
- {
- for (int i = 0; i < 3; i++)
- {
- UInt32 d[4] = { 0 };
- MyCPUID(0x80000002 + i, &d[0], &d[1], &d[2], &d[3]);
- for (int j = 0; j < 4; j++)
- PrintCpuChars(s, d[j]);
- }
- }
-
- s.Add_Space_if_NotEmpty();
- {
- char temp[32];
- ConvertUInt32ToHex(c.ver, temp);
- s += '(';
- s += temp;
- s += ')';
- }
+ PrintRequirements(f, "usage:", true, usage, "Benchmark threads: ", threads);
}
-#endif
-
-void GetCpuName(AString &s)
+static void Print_Delimiter(IBenchPrintCallback &f)
{
- s.Empty();
+ f.Print(" |");
+}
- #ifdef MY_CPU_X86_OR_AMD64
- {
- Cx86cpuid cpuid;
- if (x86cpuid_CheckAndRead(&cpuid))
- {
- x86cpuid_to_String(cpuid, s);
- return;
- }
- #ifdef MY_CPU_AMD64
- s = "x64";
- #else
- s = "x86";
- #endif
- }
- #else
-
- #ifdef MY_CPU_LE
- s = "LE";
- #elif defined(MY_CPU_BE)
- s = "BE";
- #endif
+static void Print_Pow(IBenchPrintCallback &f, unsigned pow)
+{
+ char s[16];
+ ConvertUInt32ToString(pow, s);
+ unsigned pos = MyStringLen(s);
+ s[pos++] = ':';
+ s[pos] = 0;
+ PrintLeft(f, s, kFieldSize_SmallName); // 4
+}
- #endif
+static void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f,
+ UInt64 usage, UInt64 speed)
+{
+ PrintUsage(f, usage, kFieldSize_Usage);
+ PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed);
}
@@ -2446,38 +3624,87 @@ HRESULT Bench(
IBenchCallback *benchCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
- bool multiDict)
+ bool multiDict,
+ IBenchFreqCallback *freqCallback)
{
if (!CrcInternalTest())
- return S_FALSE;
+ return E_FAIL;
UInt32 numCPUs = 1;
UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
- #ifndef _7ZIP_ST
- numCPUs = NSystem::GetNumberOfProcessors();
+ NSystem::CProcessAffinity threadsInfo;
+ threadsInfo.InitST();
+
+ #ifndef Z7_ST
+
+ if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0)
+ numCPUs = threadsInfo.GetNumProcessThreads();
+ else
+ numCPUs = NSystem::GetNumberOfProcessors();
+
#endif
+
+ // numCPUs = 24;
+ /*
+ {
+ DWORD_PTR mask = (1 << 0);
+ DWORD_PTR old = SetThreadAffinityMask(GetCurrentThread(), mask);
+ old = old;
+ DWORD_PTR old2 = SetThreadAffinityMask(GetCurrentThread(), mask);
+ old2 = old2;
+ return 0;
+ }
+ */
bool ramSize_Defined = NSystem::GetRamSize(ramSize);
UInt32 numThreadsSpecified = numCPUs;
-
- UInt32 testTime = kComplexInSeconds;
-
+ bool needSetComplexity = false;
+ UInt32 testTimeMs = kComplexInMs;
+ UInt32 startDicLog = 22;
+ bool startDicLog_Defined = false;
UInt64 specifiedFreq = 0;
-
bool multiThreadTests = false;
+ UInt64 complexInCommands = kComplexInCommands;
+ UInt32 numThreads_Start = 1;
+
+ #ifndef Z7_ST
+ CAffinityMode affinityMode;
+ #endif
+
COneMethodInfo method;
- CBenchBuffer fileDataBuffer;
+ CMidAlignedBuffer fileDataBuffer;
+ bool use_fileData = false;
+ bool isFixedDict = false;
{
unsigned i;
+
+ if (printCallback)
+ {
+ for (i = 0; i < props.Size(); i++)
+ {
+ const CProperty &property = props[i];
+ printCallback->Print(" ");
+ printCallback->Print(GetAnsiString(property.Name));
+ if (!property.Value.IsEmpty())
+ {
+ printCallback->Print("=");
+ printCallback->Print(GetAnsiString(property.Value));
+ }
+ }
+ if (!props.IsEmpty())
+ printCallback->NewLine();
+ }
+
+
for (i = 0; i < props.Size(); i++)
{
const CProperty &property = props[i];
- UString name = property.Name;
+ UString name (property.Name);
name.MakeLower_Ascii();
if (name.IsEqualTo("file"))
@@ -2485,36 +3712,38 @@ HRESULT Bench(
if (property.Value.IsEmpty())
return E_INVALIDARG;
- #ifdef USE_WIN_FILE
-
NFile::NIO::CInFile file;
if (!file.Open(us2fs(property.Value)))
- return E_INVALIDARG;
- UInt64 len;
- if (!file.GetLength(len))
- return E_FAIL;
- if (len >= ((UInt32)1 << 31) || len == 0)
- return E_INVALIDARG;
- if (!fileDataBuffer.Alloc((size_t)len))
- return E_OUTOFMEMORY;
- UInt32 processedSize;
- file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize);
- if (processedSize != len)
- return E_FAIL;
- if (printCallback)
+ return GetLastError_noZero_HRESULT();
+ size_t len;
{
- printCallback->Print("file size =");
- // printCallback->Print(GetOemString(property.Value));
- PrintNumber(*printCallback, len, 0);
- printCallback->NewLine();
+ UInt64 len64;
+ if (!file.GetLength(len64))
+ return GetLastError_noZero_HRESULT();
+ if (printCallback)
+ {
+ printCallback->Print("file size =");
+ PrintNumber(*printCallback, len64, 0);
+ printCallback->NewLine();
+ }
+ len = (size_t)len64;
+ if (len != len64)
+ return E_INVALIDARG;
}
- continue;
- #else
+ // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here
- return E_NOTIMPL;
+ ALLOC_WITH_HRESULT(&fileDataBuffer, len)
+ use_fileData = true;
- #endif
+ {
+ size_t processed;
+ if (!file.ReadFull((Byte *)fileDataBuffer, len, processed))
+ return GetLastError_noZero_HRESULT();
+ if (processed != len)
+ return E_FAIL;
+ }
+ continue;
}
NCOM::CPropVariant propVariant;
@@ -2523,14 +3752,65 @@ HRESULT Bench(
if (name.IsEqualTo("time"))
{
- RINOK(ParsePropToUInt32(L"", propVariant, testTime));
+ RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
+ needSetComplexity = true;
+ testTimeMs *= 1000;
continue;
}
-
+
+ if (name.IsEqualTo("timems"))
+ {
+ RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
+ needSetComplexity = true;
+ continue;
+ }
+
+ if (name.IsEqualTo("tic"))
+ {
+ UInt32 v;
+ RINOK(ParsePropToUInt32(UString(), propVariant, v))
+ if (v >= 64)
+ return E_INVALIDARG;
+ complexInCommands = (UInt64)1 << v;
+ continue;
+ }
+
+ const bool isCurrent_fixedDict = name.IsEqualTo("df");
+ if (isCurrent_fixedDict)
+ isFixedDict = true;
+ if (isCurrent_fixedDict || name.IsEqualTo("ds"))
+ {
+ RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog))
+ if (startDicLog > 32)
+ return E_INVALIDARG;
+ startDicLog_Defined = true;
+ continue;
+ }
+
+ if (name.IsEqualTo("mts"))
+ {
+ RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start))
+ continue;
+ }
+
+ if (name.IsEqualTo("af"))
+ {
+ UInt32 bundle;
+ RINOK(ParsePropToUInt32(UString(), propVariant, bundle))
+ if (bundle > 0 && bundle < numCPUs)
+ {
+ #ifndef Z7_ST
+ affinityMode.SetLevels(numCPUs, 2);
+ affinityMode.NumBundleThreads = bundle;
+ #endif
+ }
+ continue;
+ }
+
if (name.IsEqualTo("freq"))
{
UInt32 freq32 = 0;
- RINOK(ParsePropToUInt32(L"", propVariant, freq32));
+ RINOK(ParsePropToUInt32(UString(), propVariant, freq32))
if (freq32 == 0)
return E_INVALIDARG;
specifiedFreq = (UInt64)freq32 * 1000000;
@@ -2547,46 +3827,48 @@ HRESULT Bench(
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
- UString s = name.Ptr(2);
- if (s == L"*")
+ const UString s = name.Ptr(2);
+ if (s.IsEqualTo("*")
+ || (s.IsEmpty()
+ && propVariant.vt == VT_BSTR
+ && StringsAreEqual_Ascii(propVariant.bstrVal, "*")))
{
multiThreadTests = true;
continue;
}
- if (s.IsEmpty() && propVariant.vt == VT_BSTR)
- {
- if (wcscmp(propVariant.bstrVal, L"*") == 0)
- {
- multiThreadTests = true;
- continue;
- }
- }
- #ifndef _7ZIP_ST
- RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified));
+ #ifndef Z7_ST
+ RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified))
#endif
continue;
}
- RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant));
+ RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant))
}
}
if (printCallback)
{
AString s;
- GetCpuName(s);
+
+ #ifndef _WIN32
+ s += "Compiler: ";
+ GetCompiler(s);
+ printCallback->Print(s);
+ printCallback->NewLine();
+ s.Empty();
+ #endif
+
+ GetSystemInfoText(s);
printCallback->Print(s);
printCallback->NewLine();
}
if (printCallback)
{
- printCallback->Print("CPU Freq:");
+ printCallback->Print("1T CPU Freq (MHz):");
}
- UInt64 complexInCommands = kComplexInCommands;
-
- if (printCallback /* || benchCallback */)
+ if (printCallback || freqCallback)
{
UInt64 numMilCommands = 1 << 6;
if (specifiedFreq != 0)
@@ -2598,17 +3880,23 @@ HRESULT Bench(
for (int jj = 0;; jj++)
{
if (printCallback)
- RINOK(printCallback->CheckBreak());
+ RINOK(printCallback->CheckBreak())
UInt64 start = ::GetTimeCount();
UInt32 sum = (UInt32)start;
sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
+ if (sum == 0xF1541213)
+ if (printCallback)
+ printCallback->Print("");
const UInt64 realDelta = ::GetTimeCount() - start;
start = realDelta;
if (start == 0)
start = 1;
- UInt64 freq = GetFreq();
+ if (start > (UInt64)1 << 61)
+ start = 1;
+ const UInt64 freq = GetFreq();
// mips is constant in some compilers
+ const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, freq, start);
const UInt64 mipsVal = numMilCommands * freq / start;
if (printCallback)
{
@@ -2619,172 +3907,570 @@ HRESULT Bench(
else
{
// PrintNumber(*printCallback, start, 0);
- PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
+ PrintNumber(*printCallback, mipsVal, 5);
}
}
- /*
- if (benchCallback)
- benchCallback->AddCpuFreq(mipsVal);
- */
+ if (freqCallback)
+ {
+ RINOK(freqCallback->AddCpuFreq(1, hz, kBenchmarkUsageMult))
+ }
+
+ if (jj >= 1)
+ {
+ bool needStop = (numMilCommands >= (1 <<
+ #ifdef _DEBUG
+ 7
+ #else
+ 11
+ #endif
+ ));
+ if (start >= freq * 16)
+ {
+ printCallback->Print(" (Cmplx)");
+ if (!freqCallback) // we don't want complexity change for old gui lzma benchmark
+ {
+ needSetComplexity = true;
+ }
+ needStop = true;
+ }
+ if (needSetComplexity)
+ SetComplexCommandsMs(testTimeMs, false, mipsVal * 1000000, complexInCommands);
+ if (needStop)
+ break;
+ numMilCommands <<= 1;
+ }
+ }
+ if (freqCallback)
+ {
+ RINOK(freqCallback->FreqsFinished(1))
+ }
+ }
+
+ if (numThreadsSpecified >= 2)
+ if (printCallback || freqCallback)
+ {
+ if (printCallback)
+ printCallback->NewLine();
- if (jj >= 3)
+ /* it can show incorrect frequency for HT threads.
+ so we reduce freq test to (numCPUs / 2) */
+
+ UInt32 numThreads = numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2: numThreadsSpecified;
+ if (numThreads < 1)
+ numThreads = 1;
+
+ if (printCallback)
+ {
+ char s[128];
+ ConvertUInt64ToString(numThreads, s);
+ printCallback->Print(s);
+ printCallback->Print("T CPU Freq (MHz):");
+ }
+ UInt64 numMilCommands = 1 <<
+ #ifdef _DEBUG
+ 7;
+ #else
+ 10;
+ #endif
+
+ if (specifiedFreq != 0)
+ {
+ while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
+ numMilCommands >>= 1;
+ }
+
+ // for (int jj = 0;; jj++)
+ for (;;)
+ {
+ if (printCallback)
+ RINOK(printCallback->CheckBreak())
+
+ {
+ // PrintLeft(f, "CPU", kFieldSize_Name);
+
+ // UInt32 resVal;
+
+ CFreqBench fb;
+ fb.complexInCommands = numMilCommands * 1000000;
+ fb.numThreads = numThreads;
+ // showFreq;
+ // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
+ fb.showFreq = true;
+ fb.specifiedFreq = 1;
+
+ const HRESULT res = fb.FreqBench(NULL /* printCallback */
+ #ifndef Z7_ST
+ , &affinityMode
+ #endif
+ );
+ RINOK(res)
+
+ if (freqCallback)
+ {
+ RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes))
+ }
+
+ if (printCallback)
+ {
+ /*
+ if (realDelta == 0)
+ {
+ printCallback->Print(" -");
+ }
+ else
+ */
+ {
+ // PrintNumber(*printCallback, start, 0);
+ PrintUsage(*printCallback, fb.UsageRes, 3);
+ printCallback->Print("%");
+ PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0);
+ printCallback->Print(" ");
+
+ // PrintNumber(*printCallback, fb.UsageRes, 5);
+ }
+ }
+ }
+ // if (jj >= 1)
{
- SetComplexCommands(testTime, false, mipsVal * 1000000, complexInCommands);
- if (jj >= 8 || start >= freq)
+ const bool needStop = (numMilCommands >= (1 <<
+ #ifdef _DEBUG
+ 7
+ #else
+ 11
+ #endif
+ ));
+ if (needStop)
break;
- // break; // change it
numMilCommands <<= 1;
}
}
+ if (freqCallback)
+ {
+ RINOK(freqCallback->FreqsFinished(numThreads))
+ }
}
+
if (printCallback)
{
printCallback->NewLine();
printCallback->NewLine();
PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
+ printCallback->Print(GetProcessThreadsInfo(threadsInfo));
+ printCallback->NewLine();
}
if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
return E_INVALIDARG;
- UInt32 dict;
- bool dictIsDefined = method.Get_DicSize(dict);
+ UInt64 dict = (UInt64)1 << startDicLog;
+ const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict));
+
+ const unsigned level = method.GetLevel();
- if (method.MethodName.IsEmpty())
- method.MethodName = "LZMA";
+ AString &methodName = method.MethodName;
+ const AString original_MethodName = methodName;
+ if (methodName.IsEmpty())
+ methodName = "LZMA";
if (benchCallback)
{
CBenchProps benchProps;
benchProps.SetLzmaCompexity();
- UInt32 dictSize = method.Get_Lzma_DicSize();
- UInt32 uncompressedDataSize = kAdditionalSize + dictSize;
+ const UInt64 dictSize = method.Get_Lzma_DicSize();
+
+ size_t uncompressedDataSize;
+ if (use_fileData)
+ {
+ uncompressedDataSize = fileDataBuffer.Size();
+ }
+ else
+ {
+ uncompressedDataSize = kAdditionalSize + (size_t)dictSize;
+ if (uncompressedDataSize < dictSize)
+ return E_INVALIDARG;
+ }
+
return MethodBench(
EXTERNAL_CODECS_LOC_VARS
complexInCommands,
+ #ifndef Z7_ST
true, numThreadsSpecified,
+ &affinityMode,
+ #endif
method,
- uncompressedDataSize, fileDataBuffer.Buffer,
+ uncompressedDataSize, (const Byte *)fileDataBuffer,
kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
}
- AString methodName = method.MethodName;
if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
methodName = "crc32";
- method.MethodName = methodName;
+
CMethodId hashID;
-
- if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID))
+ const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID);
+ int codecIndex = -1;
+ bool isFilter = false;
+ if (!isHashMethod)
+ {
+ UInt32 numStreams;
+ codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName,
+ true, // encode
+ hashID, numStreams, isFilter);
+ // we can allow non filter for BW tests
+ if (!isFilter) codecIndex = -1;
+ }
+
+ CBenchCallbackToPrint callback;
+ callback.Init();
+ callback._file = printCallback;
+
+ if (isHashMethod || codecIndex != -1)
{
if (!printCallback)
return S_FALSE;
IBenchPrintCallback &f = *printCallback;
+
+ UInt64 dict64 = dict;
if (!dictIsDefined)
- dict = (1 << 24);
+ dict64 = (1 << 27);
+ if (use_fileData)
+ {
+ if (!dictIsDefined)
+ dict64 = fileDataBuffer.Size();
+ else if (dict64 > fileDataBuffer.Size())
+ dict64 = fileDataBuffer.Size();
+ }
+ for (;;)
+ {
+ const int index = method.FindProp(NCoderPropID::kDictionarySize);
+ if (index < 0)
+ break;
+ method.Props.Delete((unsigned)index);
+ }
- // methhodName.RemoveChar(L'-');
- UInt32 complexity = 10000;
+ // methodName.RemoveChar(L'-');
+ Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method
const UInt32 *checkSum = NULL;
+ int benchIndex = -1;
+
+ if (isHashMethod)
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
{
const CBenchHash &h = g_Hash[i];
- AString s = h.Name;
- AString hProp;
- int propPos = s.Find(':');
+ AString benchMethod (h.Name);
+ AString benchProps;
+ const int propPos = benchMethod.Find(':');
if (propPos >= 0)
{
- hProp = s.Ptr(propPos + 1);
- s.DeleteFrom(propPos);
+ benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
+ benchMethod.DeleteFrom((unsigned)propPos);
}
- if (AreSameMethodNames(s, methodName))
+ if (AreSameMethodNames(benchMethod, methodName))
{
- complexity = h.Complex;
- checkSum = &h.CheckSum;
- if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp))
- break;
+ const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
+ /*
+ bool isMainMethod = method.PropsString.IsEmpty();
+ if (isMainMethod)
+ isMainMethod = !checkSum
+ || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8"));
+ if (sameProps || isMainMethod)
+ */
+ {
+ complexity = (Int32)h.Complex;
+ checkSum = &h.CheckSum;
+ if (sameProps)
+ break;
+ /*
+ if property. is not specified, we use the complexity
+ for latest fastest method (crc32:64)
+ */
+ }
+ }
+ }
+ // if (!checkSum) return E_NOTIMPL;
+ }
+ else
+ {
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
+ {
+ const CBenchMethod &bench = g_Bench[i];
+ AString benchMethod (bench.Name);
+ AString benchProps;
+ const int propPos = benchMethod.Find(':');
+ if (propPos >= 0)
+ {
+ benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
+ benchMethod.DeleteFrom((unsigned)propPos);
+ }
+
+ if (AreSameMethodNames(benchMethod, methodName))
+ {
+ const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
+ // bool isMainMethod = method.PropsString.IsEmpty();
+ // if (sameProps || isMainMethod)
+ {
+ benchIndex = (int)i;
+ if (sameProps)
+ break;
+ }
}
}
+ // if (benchIndex < 0) return E_NOTIMPL;
}
- f.NewLine();
- f.Print("Size");
- const unsigned kFieldSize_CrcSpeed = 6;
- unsigned numThreadsTests = 0;
- for (;;)
{
- UInt32 t = GetNumThreadsNext(numThreadsTests, numThreadsSpecified);
- PrintNumber(f, t, kFieldSize_CrcSpeed);
- numThreadsTests++;
- if (t >= numThreadsSpecified)
- break;
+ /* we count usage only for crc and filter. non-filters are not supported */
+ UInt64 usage = (1 << 20);
+ UInt64 bufSize = dict64;
+ UInt32 numBlocks = isHashMethod ? 1 : 3;
+ if (use_fileData)
+ {
+ usage += fileDataBuffer.Size();
+ if (bufSize > fileDataBuffer.Size())
+ bufSize = fileDataBuffer.Size();
+ if (isHashMethod)
+ {
+ numBlocks = 0;
+ #ifndef Z7_ST
+ if (numThreadsSpecified != 1)
+ numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0);
+ #endif
+ }
+ }
+ usage += numThreadsSpecified * bufSize * numBlocks;
+ Print_Usage_and_Threads(f, usage, numThreadsSpecified);
}
+
+ CUIntVector numThreadsVector;
+ {
+ unsigned nt = numThreads_Start;
+ for (;;)
+ {
+ if (nt > numThreadsSpecified)
+ break;
+ numThreadsVector.Add(nt);
+ const unsigned next = nt * 2;
+ const UInt32 ntHalf= numThreadsSpecified / 2;
+ if (ntHalf > nt && ntHalf < next)
+ numThreadsVector.Add(ntHalf);
+ if (numThreadsSpecified > nt && numThreadsSpecified < next)
+ numThreadsVector.Add(numThreadsSpecified);
+ nt = next;
+ }
+ }
+
+ unsigned numColumns = isHashMethod ? 1 : 2;
+ CTempValues speedTotals;
+ CTempValues usageTotals;
+ {
+ const unsigned numItems = numThreadsVector.Size() * numColumns;
+ speedTotals.Alloc(numItems);
+ usageTotals.Alloc(numItems);
+ for (unsigned i = 0; i < numItems; i++)
+ {
+ speedTotals.Values[i] = 0;
+ usageTotals.Values[i] = 0;
+ }
+ }
+
f.NewLine();
- f.NewLine();
- CTempValues speedTotals(numThreadsTests);
+ for (unsigned line = 0; line < 3; line++)
{
- for (unsigned ti = 0; ti < numThreadsTests; ti++)
- speedTotals.Values[ti] = 0;
+ f.NewLine();
+ f.Print(line == 0 ? "THRD" : line == 1 ? " " : "Size");
+ FOR_VECTOR (ti, numThreadsVector)
+ {
+ if (ti != 0)
+ Print_Delimiter(f);
+ if (line == 0)
+ {
+ PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1));
+ PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed);
+ }
+ else
+ {
+ for (unsigned c = 0; c < numColumns; c++)
+ {
+ PrintRight(f, line == 1 ? "Usage" : "%", kFieldSize_Usage + 1);
+ PrintRight(f, line == 1 ? "BW" : "MB/s", kFieldSize_CrcSpeed + 1);
+ }
+ }
+ }
}
-
+ f.NewLine();
+
UInt64 numSteps = 0;
- for (UInt32 i = 0; i < numIterations; i++)
+
+ // for (UInt32 iter = 0; iter < numIterations; iter++)
+ // {
+ unsigned pow = 10; // kNumHashDictBits
+ if (startDicLog_Defined)
+ pow = startDicLog;
+
+ // #define NUM_SUB_BITS 2
+ // pow <<= NUM_SUB_BITS;
+ for (;; pow++)
{
- for (unsigned pow = 10; pow < 32; pow++)
+ const UInt64 bufSize = (UInt64)1 << pow;
+ // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS);
+ // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS);
+
+ size_t dataSize = fileDataBuffer.Size();
+ if (dataSize > bufSize || !use_fileData)
+ dataSize = (size_t)bufSize;
+
+ for (UInt32 iter = 0; iter < numIterations; iter++)
{
- UInt32 bufSize = (UInt32)1 << pow;
- if (bufSize > dict)
- break;
- char s[16];
- ConvertUInt32ToString(pow, s);
- unsigned pos = MyStringLen(s);
- s[pos++] = ':';
- s[pos++] = ' ';
- s[pos] = 0;
- f.Print(s);
-
- for (unsigned ti = 0; ti < numThreadsTests; ti++)
+ Print_Pow(f, pow);
+ // PrintNumber(f, bufSize >> 10, 4);
+
+ FOR_VECTOR (ti, numThreadsVector)
{
- RINOK(f.CheckBreak());
- UInt32 t = GetNumThreadsNext(ti, numThreadsSpecified);
- UInt64 speed = 0;
- RINOK(CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
- t, bufSize, speed,
- complexity,
+ RINOK(f.CheckBreak())
+ const UInt32 numThreads = numThreadsVector[ti];
+ if (isHashMethod)
+ {
+ UInt64 speed = 0;
+ UInt64 usage = 0;
+ const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
+ numThreads,
+ dataSize, (const Byte *)fileDataBuffer,
+ speed, usage,
+ (UInt32)complexity,
1, // benchWeight,
- (pow == kNumHashDictBits) ? checkSum : NULL, method, NULL, NULL, false, 0));
- PrintNumber(f, (speed >> 20), kFieldSize_CrcSpeed);
- speedTotals.Values[ti] += speed;
+ (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL,
+ method,
+ &f,
+ #ifndef Z7_ST
+ &affinityMode,
+ #endif
+ false, // showRating
+ NULL, false, 0);
+ RINOK(res)
+
+ if (ti != 0)
+ Print_Delimiter(f);
+
+ Bench_BW_Print_Usage_Speed(f, usage, speed);
+ speedTotals.Values[ti] += speed;
+ usageTotals.Values[ti] += usage;
+ }
+ else
+ {
+ {
+ unsigned keySize = 32;
+ if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16;
+ else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24;
+ callback.BenchProps.KeySize = keySize;
+ }
+
+ COneMethodInfo method2 = method;
+ unsigned bench_DictBits;
+
+ if (benchIndex >= 0)
+ {
+ const CBenchMethod &bench = g_Bench[benchIndex];
+ callback.BenchProps.EncComplex = bench.EncComplex;
+ callback.BenchProps.DecComplexUnc = bench.DecComplexUnc;
+ callback.BenchProps.DecComplexCompr = bench.DecComplexCompr;
+ bench_DictBits = bench.DictBits;
+ // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug
+ }
+ else
+ {
+ bench_DictBits = kOldLzmaDictBits; // = 32 default
+ if (isFilter)
+ {
+ const unsigned k_UnknownCoderComplexity = 4;
+ callback.BenchProps.EncComplex = k_UnknownCoderComplexity;
+ callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity;
+ }
+ else
+ {
+ callback.BenchProps.EncComplex = 1 << 10;
+ callback.BenchProps.DecComplexUnc = 1 << 6;
+ }
+ callback.BenchProps.DecComplexCompr = 0;
+ }
+ callback.NeedPrint = false;
+
+ if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
+ {
+ const NCOM::CPropVariant propVariant = (UInt32)pow;
+ RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
+ }
+
+ const HRESULT res = MethodBench(
+ EXTERNAL_CODECS_LOC_VARS
+ complexInCommands,
+ #ifndef Z7_ST
+ false, // oldLzmaBenchMode
+ numThreadsVector[ti],
+ &affinityMode,
+ #endif
+ method2,
+ dataSize, (const Byte *)fileDataBuffer,
+ bench_DictBits,
+ printCallback,
+ &callback,
+ &callback.BenchProps);
+ RINOK(res)
+
+ if (ti != 0)
+ Print_Delimiter(f);
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ const CBenchInfo &bi = callback.BenchInfo_Results[i];
+ const UInt64 usage = bi.GetUsage();
+ const UInt64 speed = bi.GetUnpackSizeSpeed();
+ usageTotals.Values[ti * 2 + i] += usage;
+ speedTotals.Values[ti * 2 + i] += speed;
+ Bench_BW_Print_Usage_Speed(f, usage, speed);
+ }
+ }
}
+
f.NewLine();
numSteps++;
}
+ if (dataSize >= dict64)
+ break;
}
+
if (numSteps != 0)
{
- f.NewLine();
f.Print("Avg:");
- for (unsigned ti = 0; ti < numThreadsTests; ti++)
+ for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++)
{
- PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), kFieldSize_CrcSpeed);
+ if (ti != 0)
+ Print_Delimiter(f);
+ for (unsigned i = 0; i < numColumns; i++)
+ Bench_BW_Print_Usage_Speed(f,
+ usageTotals.Values[ti * numColumns + i] / numSteps,
+ speedTotals.Values[ti * numColumns + i] / numSteps);
}
f.NewLine();
}
+
return S_OK;
}
bool use2Columns = false;
- bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*"));
+ bool totalBenchMode = false;
bool onlyHashBench = false;
- if (method.MethodName.IsEqualTo_Ascii_NoCase("hash"))
+ if (methodName.IsEqualTo_Ascii_NoCase("hash"))
{
onlyHashBench = true;
+ methodName = "*";
totalBenchMode = true;
}
+ else if (methodName.Find('*') >= 0)
+ totalBenchMode = true;
// ---------- Threads loop ----------
for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++)
@@ -2815,10 +4501,6 @@ HRESULT Bench(
}
}
- CBenchCallbackToPrint callback;
- callback.Init();
- callback._file = printCallback;
-
IBenchPrintCallback &f = *printCallback;
if (threadsPassIndex > 0)
@@ -2827,7 +4509,7 @@ HRESULT Bench(
f.NewLine();
}
- if (!dictIsDefined)
+ if (!dictIsDefined && !onlyHashBench)
{
const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
unsigned dicSizeLog = dicSizeLog_Main;
@@ -2838,10 +4520,10 @@ HRESULT Bench(
if (ramSize_Defined)
for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
- if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
+ if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
break;
- dict = (UInt32)1 << dicSizeLog;
+ dict = (UInt64)1 << dicSizeLog;
if (totalBenchMode && dicSizeLog != dicSizeLog_Main)
{
@@ -2851,7 +4533,13 @@ HRESULT Bench(
}
}
- PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads);
+ Print_Usage_and_Threads(f,
+ onlyHashBench ?
+ GetBenchMemoryUsage_Hash(numThreads, dict) :
+ GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode),
+ numThreads);
+
+ f.NewLine();
f.NewLine();
@@ -2934,6 +4622,7 @@ HRESULT Bench(
if (specifiedFreq != 0)
cpuFreq = specifiedFreq;
+ // bool showTotalSpeed = false;
if (totalBenchMode)
{
@@ -2941,96 +4630,171 @@ HRESULT Bench(
{
if (i != 0)
printCallback->NewLine();
- HRESULT res;
const unsigned kNumCpuTests = 3;
for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++)
{
PrintLeft(f, "CPU", kFieldSize_Name);
- UInt32 resVal;
- RINOK(FreqBench(complexInCommands, numThreads, printCallback,
- (freqTest == kNumCpuTests - 1 || specifiedFreq != 0), // showFreq
- specifiedFreq,
- cpuFreq, resVal));
+
+ // UInt32 resVal;
+
+ CFreqBench fb;
+ fb.complexInCommands = complexInCommands;
+ fb.numThreads = numThreads;
+ // showFreq;
+ fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
+ fb.specifiedFreq = specifiedFreq;
+
+ const HRESULT res = fb.FreqBench(printCallback
+ #ifndef Z7_ST
+ , &affinityMode
+ #endif
+ );
+ RINOK(res)
+
+ cpuFreq = fb.CpuFreqRes;
callback.NewLine();
if (specifiedFreq != 0)
cpuFreq = specifiedFreq;
+ if (testTimeMs >= 1000)
if (freqTest == kNumCpuTests - 1)
- SetComplexCommands(testTime, specifiedFreq != 0, cpuFreq, complexInCommands);
+ {
+ // SetComplexCommandsMs(testTimeMs, specifiedFreq != 0, cpuFreq, complexInCommands);
+ }
}
callback.NewLine();
+ // return S_OK; // change it
+
callback.SetFreq(true, cpuFreq);
if (!onlyHashBench)
{
- res = TotalBench(EXTERNAL_CODECS_LOC_VARS
- complexInCommands, numThreads,
- dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize
- fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict,
- fileDataBuffer.Buffer,
+ size_t dataSize = (size_t)dict;
+ if (use_fileData)
+ {
+ dataSize = fileDataBuffer.Size();
+ if (dictIsDefined && dataSize > dict)
+ dataSize = (size_t)dict;
+ }
+
+ const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS
+ method, complexInCommands,
+ #ifndef Z7_ST
+ numThreads,
+ &affinityMode,
+ #endif
+ dictIsDefined || use_fileData, // forceUnpackSize
+ dataSize,
+ (const Byte *)fileDataBuffer,
printCallback, &callback);
- RINOK(res);
+ RINOK(res)
}
- res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads,
- 1 << kNumHashDictBits, printCallback, &callback, &callback.EncodeRes, true, cpuFreq);
- RINOK(res);
+ {
+ size_t dataSize = (size_t)1 << kNumHashDictBits;
+ if (dictIsDefined)
+ {
+ dataSize = (size_t)dict;
+ if (dataSize != dict)
+ return E_OUTOFMEMORY;
+ }
+ if (use_fileData)
+ {
+ dataSize = fileDataBuffer.Size();
+ if (dictIsDefined && dataSize > dict)
+ dataSize = (size_t)dict;
+ }
+
+ const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS
+ method, complexInCommands,
+ numThreads,
+ dataSize, (const Byte *)fileDataBuffer,
+ printCallback, &callback,
+ #ifndef Z7_ST
+ &affinityMode,
+ #endif
+ &callback.EncodeRes, true, cpuFreq);
+ RINOK(res)
+ }
callback.NewLine();
{
PrintLeft(f, "CPU", kFieldSize_Name);
- UInt32 resVal;
- UInt64 cpuFreqLastTemp = cpuFreq;
- RINOK(FreqBench(complexInCommands, numThreads, printCallback,
- specifiedFreq != 0, // showFreq
- specifiedFreq,
- cpuFreqLastTemp, resVal));
+
+ CFreqBench fb;
+ fb.complexInCommands = complexInCommands;
+ fb.numThreads = numThreads;
+ // showFreq;
+ fb.showFreq = (specifiedFreq != 0);
+ fb.specifiedFreq = specifiedFreq;
+
+ const HRESULT res = fb.FreqBench(printCallback
+ #ifndef Z7_ST
+ , &affinityMode
+ #endif
+ );
+ RINOK(res)
callback.NewLine();
}
}
}
else
{
- bool needSetComplexity = true;
+ needSetComplexity = true;
if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
+ unsigned i;
+ for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
{
const CBenchMethod &h = g_Bench[i];
- AString s = h.Name;
- if (AreSameMethodNames(h.Name, methodName))
+ AString benchMethod (h.Name);
+ AString benchProps;
+ const int propPos = benchMethod.Find(':');
+ if (propPos >= 0)
{
- callback.BenchProps.EncComplex = h.EncComplex;
- callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
- callback.BenchProps.DecComplexUnc = h.DecComplexUnc;;
- needSetComplexity = false;
- break;
+ benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
+ benchMethod.DeleteFrom((unsigned)propPos);
+ }
+
+ if (AreSameMethodNames(benchMethod, methodName))
+ {
+ if (benchProps.IsEmpty()
+ || (benchProps == "x5" && method.PropsString.IsEmpty())
+ || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps))
+ {
+ callback.BenchProps.EncComplex = h.EncComplex;
+ callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
+ callback.BenchProps.DecComplexUnc = h.DecComplexUnc;
+ needSetComplexity = false;
+ break;
+ }
}
}
+ /*
+ if (i == Z7_ARRAY_SIZE(g_Bench))
+ return E_NOTIMPL;
+ */
}
if (needSetComplexity)
callback.BenchProps.SetLzmaCompexity();
+ if (startDicLog < kBenchMinDicLogSize)
+ startDicLog = kBenchMinDicLogSize;
+
for (unsigned i = 0; i < numIterations; i++)
{
- const unsigned kStartDicLog = 22;
- unsigned pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
+ unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog;
if (!multiDict)
- pow = 31;
- while (((UInt32)1 << pow) > dict && pow > 0)
+ pow = 32;
+ while (GetDictSizeFromLog(pow) > dict && pow > 0)
pow--;
- for (; ((UInt32)1 << pow) <= dict; pow++)
+ for (; GetDictSizeFromLog(pow) <= dict; pow++)
{
- char s[16];
- ConvertUInt32ToString(pow, s);
- unsigned pos = MyStringLen(s);
- s[pos++] = ':';
- s[pos] = 0;
- PrintLeft(f, s, kFieldSize_SmallName);
- callback.DictSize = (UInt32)1 << pow;
+ Print_Pow(f, pow);
+ callback.DictSize = (UInt64)1 << pow;
COneMethodInfo method2 = method;
@@ -3040,30 +4804,35 @@ HRESULT Bench(
// method2 can have two different dictionary size properties.
// And last property is main.
NCOM::CPropVariant propVariant = (UInt32)pow;
- RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant));
+ RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
}
size_t uncompressedDataSize;
- if (fileDataBuffer.Buffer)
+ if (use_fileData)
{
- uncompressedDataSize = fileDataBuffer.BufferSize;
+ uncompressedDataSize = fileDataBuffer.Size();
}
else
{
- uncompressedDataSize = callback.DictSize;
+ uncompressedDataSize = (size_t)callback.DictSize;
+ if (uncompressedDataSize != callback.DictSize)
+ return E_OUTOFMEMORY;
if (uncompressedDataSize >= (1 << 18))
uncompressedDataSize += kAdditionalSize;
}
- HRESULT res = MethodBench(
+ const HRESULT res = MethodBench(
EXTERNAL_CODECS_LOC_VARS
complexInCommands,
+ #ifndef Z7_ST
true, numThreads,
+ &affinityMode,
+ #endif
method2,
- uncompressedDataSize, fileDataBuffer.Buffer,
+ uncompressedDataSize, (const Byte *)fileDataBuffer,
kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
f.NewLine();
- RINOK(res);
+ RINOK(res)
if (!multiDict)
break;
}
@@ -3083,16 +4852,19 @@ HRESULT Bench(
if (use2Columns)
{
PrintLeft(f, "Avr:", callback.NameFieldSize);
- PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes);
+ PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes);
f.Print(kSep);
- PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes);
+ PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes);
f.NewLine();
}
PrintLeft(f, "Tot:", callback.NameFieldSize);
CTotalBenchRes midRes;
- midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
- PrintTotals(f, showFreq, cpuFreq, midRes);
+ midRes = callback.EncodeRes;
+ midRes.Update_With_Res(callback.DecodeRes);
+
+ // midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
+ PrintTotals(f, showFreq, cpuFreq, false, midRes);
f.NewLine();
}