1370b324cSopenharmony_ci// Bench.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../../C/CpuArch.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci// #include <stdio.h>
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#ifndef _WIN32
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#define USE_POSIX_TIME
12370b324cSopenharmony_ci#define USE_POSIX_TIME2
13370b324cSopenharmony_ci#endif // _WIN32
14370b324cSopenharmony_ci
15370b324cSopenharmony_ci#ifdef USE_POSIX_TIME
16370b324cSopenharmony_ci#include <time.h>
17370b324cSopenharmony_ci#include <unistd.h>
18370b324cSopenharmony_ci#ifdef USE_POSIX_TIME2
19370b324cSopenharmony_ci#include <sys/time.h>
20370b324cSopenharmony_ci#include <sys/times.h>
21370b324cSopenharmony_ci#endif
22370b324cSopenharmony_ci#endif // USE_POSIX_TIME
23370b324cSopenharmony_ci
24370b324cSopenharmony_ci#ifdef _WIN32
25370b324cSopenharmony_ci#define USE_ALLOCA
26370b324cSopenharmony_ci#endif
27370b324cSopenharmony_ci
28370b324cSopenharmony_ci#ifdef USE_ALLOCA
29370b324cSopenharmony_ci#ifdef _WIN32
30370b324cSopenharmony_ci#include <malloc.h>
31370b324cSopenharmony_ci#else
32370b324cSopenharmony_ci#include <stdlib.h>
33370b324cSopenharmony_ci#endif
34370b324cSopenharmony_ci#endif
35370b324cSopenharmony_ci
36370b324cSopenharmony_ci#include "../../../../C/7zCrc.h"
37370b324cSopenharmony_ci#include "../../../../C/RotateDefs.h"
38370b324cSopenharmony_ci
39370b324cSopenharmony_ci#ifndef Z7_ST
40370b324cSopenharmony_ci#include "../../../Windows/Synchronization.h"
41370b324cSopenharmony_ci#include "../../../Windows/Thread.h"
42370b324cSopenharmony_ci#endif
43370b324cSopenharmony_ci
44370b324cSopenharmony_ci#include "../../../Windows/FileFind.h"
45370b324cSopenharmony_ci#include "../../../Windows/FileIO.h"
46370b324cSopenharmony_ci#include "../../../Windows/SystemInfo.h"
47370b324cSopenharmony_ci
48370b324cSopenharmony_ci#include "../../../Common/MyBuffer2.h"
49370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
50370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
51370b324cSopenharmony_ci#include "../../../Common/StringToInt.h"
52370b324cSopenharmony_ci#include "../../../Common/Wildcard.h"
53370b324cSopenharmony_ci
54370b324cSopenharmony_ci#include "../../Common/MethodProps.h"
55370b324cSopenharmony_ci#include "../../Common/StreamObjects.h"
56370b324cSopenharmony_ci#include "../../Common/StreamUtils.h"
57370b324cSopenharmony_ci
58370b324cSopenharmony_ci#include "Bench.h"
59370b324cSopenharmony_ci
60370b324cSopenharmony_ciusing namespace NWindows;
61370b324cSopenharmony_ci
62370b324cSopenharmony_ci#ifndef Z7_ST
63370b324cSopenharmony_cistatic const UInt32 k_LZMA = 0x030101;
64370b324cSopenharmony_ci#endif
65370b324cSopenharmony_ci
66370b324cSopenharmony_cistatic const UInt64 kComplexInCommands = (UInt64)1 <<
67370b324cSopenharmony_ci  #ifdef UNDER_CE
68370b324cSopenharmony_ci    31;
69370b324cSopenharmony_ci  #else
70370b324cSopenharmony_ci    34;
71370b324cSopenharmony_ci  #endif
72370b324cSopenharmony_ci
73370b324cSopenharmony_cistatic const UInt32 kComplexInMs = 4000;
74370b324cSopenharmony_ci
75370b324cSopenharmony_cistatic void SetComplexCommandsMs(UInt32 complexInMs,
76370b324cSopenharmony_ci    bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands)
77370b324cSopenharmony_ci{
78370b324cSopenharmony_ci  complexInCommands = kComplexInCommands;
79370b324cSopenharmony_ci  const UInt64 kMinFreq = (UInt64)1000000 * 4;
80370b324cSopenharmony_ci  const UInt64 kMaxFreq = (UInt64)1000000 * 20000;
81370b324cSopenharmony_ci  if (cpuFreq < kMinFreq && !isSpecifiedFreq)
82370b324cSopenharmony_ci    cpuFreq = kMinFreq;
83370b324cSopenharmony_ci  if (cpuFreq < kMaxFreq || isSpecifiedFreq)
84370b324cSopenharmony_ci  {
85370b324cSopenharmony_ci    if (complexInMs != 0)
86370b324cSopenharmony_ci      complexInCommands = complexInMs * cpuFreq / 1000;
87370b324cSopenharmony_ci    else
88370b324cSopenharmony_ci      complexInCommands = cpuFreq >> 2;
89370b324cSopenharmony_ci  }
90370b324cSopenharmony_ci}
91370b324cSopenharmony_ci
92370b324cSopenharmony_ci// const UInt64 kBenchmarkUsageMult = 1000000; // for debug
93370b324cSopenharmony_cistatic const unsigned kBenchmarkUsageMultBits = 16;
94370b324cSopenharmony_cistatic const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits;
95370b324cSopenharmony_ci
96370b324cSopenharmony_ciUInt64 Benchmark_GetUsage_Percents(UInt64 usage)
97370b324cSopenharmony_ci{
98370b324cSopenharmony_ci  return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult;
99370b324cSopenharmony_ci}
100370b324cSopenharmony_ci
101370b324cSopenharmony_cistatic const unsigned kNumHashDictBits = 17;
102370b324cSopenharmony_cistatic const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test
103370b324cSopenharmony_ci
104370b324cSopenharmony_cistatic const unsigned kOldLzmaDictBits = 32;
105370b324cSopenharmony_ci
106370b324cSopenharmony_ci// static const size_t kAdditionalSize = (size_t)1 << 32; // for debug
107370b324cSopenharmony_cistatic const size_t kAdditionalSize = (size_t)1 << 16;
108370b324cSopenharmony_cistatic const UInt32 kCompressedAdditionalSize = (1 << 10);
109370b324cSopenharmony_ci
110370b324cSopenharmony_cistatic const UInt32 kMaxMethodPropSize = (1 << 6);
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci
113370b324cSopenharmony_ci#define ALLOC_WITH_HRESULT(_buffer_, _size_) \
114370b324cSopenharmony_ci  { (_buffer_)->Alloc(_size_); \
115370b324cSopenharmony_ci  if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; }
116370b324cSopenharmony_ci
117370b324cSopenharmony_ci
118370b324cSopenharmony_ciclass CBaseRandomGenerator
119370b324cSopenharmony_ci{
120370b324cSopenharmony_ci  UInt32 A1;
121370b324cSopenharmony_ci  UInt32 A2;
122370b324cSopenharmony_ci  UInt32 Salt;
123370b324cSopenharmony_cipublic:
124370b324cSopenharmony_ci  CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); }
125370b324cSopenharmony_ci  void Init() { A1 = 362436069; A2 = 521288629;}
126370b324cSopenharmony_ci  Z7_FORCE_INLINE
127370b324cSopenharmony_ci  UInt32 GetRnd()
128370b324cSopenharmony_ci  {
129370b324cSopenharmony_ci    return Salt ^
130370b324cSopenharmony_ci    (
131370b324cSopenharmony_ci      ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
132370b324cSopenharmony_ci      ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) )
133370b324cSopenharmony_ci    );
134370b324cSopenharmony_ci  }
135370b324cSopenharmony_ci};
136370b324cSopenharmony_ci
137370b324cSopenharmony_ci
138370b324cSopenharmony_ciZ7_NO_INLINE
139370b324cSopenharmony_cistatic void RandGen(Byte *buf, size_t size)
140370b324cSopenharmony_ci{
141370b324cSopenharmony_ci  CBaseRandomGenerator RG;
142370b324cSopenharmony_ci  const size_t size4 = size & ~((size_t)3);
143370b324cSopenharmony_ci  size_t i;
144370b324cSopenharmony_ci  for (i = 0; i < size4; i += 4)
145370b324cSopenharmony_ci  {
146370b324cSopenharmony_ci    const UInt32 v = RG.GetRnd();
147370b324cSopenharmony_ci    SetUi32(buf + i, v)
148370b324cSopenharmony_ci  }
149370b324cSopenharmony_ci  UInt32 v = RG.GetRnd();
150370b324cSopenharmony_ci  for (; i < size; i++)
151370b324cSopenharmony_ci  {
152370b324cSopenharmony_ci    buf[i] = (Byte)v;
153370b324cSopenharmony_ci    v >>= 8;
154370b324cSopenharmony_ci  }
155370b324cSopenharmony_ci}
156370b324cSopenharmony_ci
157370b324cSopenharmony_ci
158370b324cSopenharmony_ciclass CBenchRandomGenerator: public CMidAlignedBuffer
159370b324cSopenharmony_ci{
160370b324cSopenharmony_ci  static UInt32 GetVal(UInt32 &res, unsigned numBits)
161370b324cSopenharmony_ci  {
162370b324cSopenharmony_ci    UInt32 val = res & (((UInt32)1 << numBits) - 1);
163370b324cSopenharmony_ci    res >>= numBits;
164370b324cSopenharmony_ci    return val;
165370b324cSopenharmony_ci  }
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci  static UInt32 GetLen(UInt32 &r)
168370b324cSopenharmony_ci  {
169370b324cSopenharmony_ci    UInt32 len = GetVal(r, 2);
170370b324cSopenharmony_ci    return GetVal(r, 1 + len);
171370b324cSopenharmony_ci  }
172370b324cSopenharmony_ci
173370b324cSopenharmony_cipublic:
174370b324cSopenharmony_ci
175370b324cSopenharmony_ci  void GenerateSimpleRandom(UInt32 salt)
176370b324cSopenharmony_ci  {
177370b324cSopenharmony_ci    CBaseRandomGenerator rg(salt);
178370b324cSopenharmony_ci    const size_t bufSize = Size();
179370b324cSopenharmony_ci    Byte *buf = (Byte *)*this;
180370b324cSopenharmony_ci    for (size_t i = 0; i < bufSize; i++)
181370b324cSopenharmony_ci      buf[i] = (Byte)rg.GetRnd();
182370b324cSopenharmony_ci  }
183370b324cSopenharmony_ci
184370b324cSopenharmony_ci  void GenerateLz(unsigned dictBits, UInt32 salt)
185370b324cSopenharmony_ci  {
186370b324cSopenharmony_ci    CBaseRandomGenerator rg(salt);
187370b324cSopenharmony_ci    size_t pos = 0;
188370b324cSopenharmony_ci    size_t rep0 = 1;
189370b324cSopenharmony_ci    const size_t bufSize = Size();
190370b324cSopenharmony_ci    Byte *buf = (Byte *)*this;
191370b324cSopenharmony_ci    unsigned posBits = 1;
192370b324cSopenharmony_ci
193370b324cSopenharmony_ci    // printf("\n dictBits = %d\n", (UInt32)dictBits);
194370b324cSopenharmony_ci    // printf("\n bufSize = 0x%p\n", (const void *)bufSize);
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci    while (pos < bufSize)
197370b324cSopenharmony_ci    {
198370b324cSopenharmony_ci      /*
199370b324cSopenharmony_ci      if (pos >= ((UInt32)1 << 31))
200370b324cSopenharmony_ci        printf(" %x\n", pos);
201370b324cSopenharmony_ci      */
202370b324cSopenharmony_ci      UInt32 r = rg.GetRnd();
203370b324cSopenharmony_ci      if (GetVal(r, 1) == 0 || pos < 1024)
204370b324cSopenharmony_ci        buf[pos++] = (Byte)(r & 0xFF);
205370b324cSopenharmony_ci      else
206370b324cSopenharmony_ci      {
207370b324cSopenharmony_ci        UInt32 len;
208370b324cSopenharmony_ci        len = 1 + GetLen(r);
209370b324cSopenharmony_ci
210370b324cSopenharmony_ci        if (GetVal(r, 3) != 0)
211370b324cSopenharmony_ci        {
212370b324cSopenharmony_ci          len += GetLen(r);
213370b324cSopenharmony_ci
214370b324cSopenharmony_ci          while (((size_t)1 << posBits) < pos)
215370b324cSopenharmony_ci            posBits++;
216370b324cSopenharmony_ci
217370b324cSopenharmony_ci          unsigned numBitsMax = dictBits;
218370b324cSopenharmony_ci          if (numBitsMax > posBits)
219370b324cSopenharmony_ci            numBitsMax = posBits;
220370b324cSopenharmony_ci
221370b324cSopenharmony_ci          const unsigned kAddBits = 6;
222370b324cSopenharmony_ci          unsigned numLogBits = 5;
223370b324cSopenharmony_ci          if (numBitsMax <= (1 << 4) - 1 + kAddBits)
224370b324cSopenharmony_ci            numLogBits = 4;
225370b324cSopenharmony_ci
226370b324cSopenharmony_ci          for (;;)
227370b324cSopenharmony_ci          {
228370b324cSopenharmony_ci            const UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
229370b324cSopenharmony_ci            r = rg.GetRnd();
230370b324cSopenharmony_ci            if (ppp > numBitsMax)
231370b324cSopenharmony_ci              continue;
232370b324cSopenharmony_ci            // rep0 = GetVal(r, ppp);
233370b324cSopenharmony_ci            rep0 = r & (((size_t)1 << ppp) - 1);
234370b324cSopenharmony_ci            if (rep0 < pos)
235370b324cSopenharmony_ci              break;
236370b324cSopenharmony_ci            r = rg.GetRnd();
237370b324cSopenharmony_ci          }
238370b324cSopenharmony_ci          rep0++;
239370b324cSopenharmony_ci        }
240370b324cSopenharmony_ci
241370b324cSopenharmony_ci        // len *= 300; // for debug
242370b324cSopenharmony_ci        {
243370b324cSopenharmony_ci          const size_t rem = bufSize - pos;
244370b324cSopenharmony_ci          if (len > rem)
245370b324cSopenharmony_ci            len = (UInt32)rem;
246370b324cSopenharmony_ci        }
247370b324cSopenharmony_ci        Byte *dest = buf + pos;
248370b324cSopenharmony_ci        const Byte *src = dest - rep0;
249370b324cSopenharmony_ci        pos += len;
250370b324cSopenharmony_ci        for (UInt32 i = 0; i < len; i++)
251370b324cSopenharmony_ci          *dest++ = *src++;
252370b324cSopenharmony_ci      }
253370b324cSopenharmony_ci    }
254370b324cSopenharmony_ci    // printf("\n CRC = %x\n", CrcCalc(buf, bufSize));
255370b324cSopenharmony_ci  }
256370b324cSopenharmony_ci};
257370b324cSopenharmony_ci
258370b324cSopenharmony_ci
259370b324cSopenharmony_ciZ7_CLASS_IMP_NOQIB_1(
260370b324cSopenharmony_ci  CBenchmarkInStream
261370b324cSopenharmony_ci  , ISequentialInStream
262370b324cSopenharmony_ci)
263370b324cSopenharmony_ci  const Byte *Data;
264370b324cSopenharmony_ci  size_t Pos;
265370b324cSopenharmony_ci  size_t Size;
266370b324cSopenharmony_cipublic:
267370b324cSopenharmony_ci  void Init(const Byte *data, size_t size)
268370b324cSopenharmony_ci  {
269370b324cSopenharmony_ci    Data = data;
270370b324cSopenharmony_ci    Size = size;
271370b324cSopenharmony_ci    Pos = 0;
272370b324cSopenharmony_ci  }
273370b324cSopenharmony_ci  bool WasFinished() const { return Pos == Size; }
274370b324cSopenharmony_ci};
275370b324cSopenharmony_ci
276370b324cSopenharmony_ciZ7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
277370b324cSopenharmony_ci{
278370b324cSopenharmony_ci  const UInt32 kMaxBlockSize = (1 << 20);
279370b324cSopenharmony_ci  if (size > kMaxBlockSize)
280370b324cSopenharmony_ci    size = kMaxBlockSize;
281370b324cSopenharmony_ci  const size_t remain = Size - Pos;
282370b324cSopenharmony_ci  if (size > remain)
283370b324cSopenharmony_ci    size = (UInt32)remain;
284370b324cSopenharmony_ci
285370b324cSopenharmony_ci  if (size != 0)
286370b324cSopenharmony_ci    memcpy(data, Data + Pos, size);
287370b324cSopenharmony_ci
288370b324cSopenharmony_ci  Pos += size;
289370b324cSopenharmony_ci  if (processedSize)
290370b324cSopenharmony_ci    *processedSize = size;
291370b324cSopenharmony_ci  return S_OK;
292370b324cSopenharmony_ci}
293370b324cSopenharmony_ci
294370b324cSopenharmony_ci
295370b324cSopenharmony_ciclass CBenchmarkOutStream Z7_final:
296370b324cSopenharmony_ci  public ISequentialOutStream,
297370b324cSopenharmony_ci  public CMyUnknownImp,
298370b324cSopenharmony_ci  public CMidAlignedBuffer
299370b324cSopenharmony_ci{
300370b324cSopenharmony_ci  Z7_COM_UNKNOWN_IMP_0
301370b324cSopenharmony_ci  Z7_IFACE_COM7_IMP(ISequentialOutStream)
302370b324cSopenharmony_ci  // bool _overflow;
303370b324cSopenharmony_cipublic:
304370b324cSopenharmony_ci  size_t Pos;
305370b324cSopenharmony_ci  bool RealCopy;
306370b324cSopenharmony_ci  bool CalcCrc;
307370b324cSopenharmony_ci  UInt32 Crc;
308370b324cSopenharmony_ci
309370b324cSopenharmony_ci  // CBenchmarkOutStream(): _overflow(false) {}
310370b324cSopenharmony_ci  void Init(bool realCopy, bool calcCrc)
311370b324cSopenharmony_ci  {
312370b324cSopenharmony_ci    Crc = CRC_INIT_VAL;
313370b324cSopenharmony_ci    RealCopy = realCopy;
314370b324cSopenharmony_ci    CalcCrc = calcCrc;
315370b324cSopenharmony_ci    // _overflow = false;
316370b324cSopenharmony_ci    Pos = 0;
317370b324cSopenharmony_ci  }
318370b324cSopenharmony_ci
319370b324cSopenharmony_ci  void InitCrc()
320370b324cSopenharmony_ci  {
321370b324cSopenharmony_ci    Crc = CRC_INIT_VAL;
322370b324cSopenharmony_ci  }
323370b324cSopenharmony_ci
324370b324cSopenharmony_ci  void Calc(const void *data, size_t size)
325370b324cSopenharmony_ci  {
326370b324cSopenharmony_ci    Crc = CrcUpdate(Crc, data, size);
327370b324cSopenharmony_ci  }
328370b324cSopenharmony_ci
329370b324cSopenharmony_ci  size_t GetPos() const { return Pos; }
330370b324cSopenharmony_ci
331370b324cSopenharmony_ci  // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
332370b324cSopenharmony_ci};
333370b324cSopenharmony_ci
334370b324cSopenharmony_ciZ7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
335370b324cSopenharmony_ci{
336370b324cSopenharmony_ci  size_t curSize = Size() - Pos;
337370b324cSopenharmony_ci  if (curSize > size)
338370b324cSopenharmony_ci    curSize = size;
339370b324cSopenharmony_ci  if (curSize != 0)
340370b324cSopenharmony_ci  {
341370b324cSopenharmony_ci    if (RealCopy)
342370b324cSopenharmony_ci      memcpy(((Byte *)*this) + Pos, data, curSize);
343370b324cSopenharmony_ci    if (CalcCrc)
344370b324cSopenharmony_ci      Calc(data, curSize);
345370b324cSopenharmony_ci    Pos += curSize;
346370b324cSopenharmony_ci  }
347370b324cSopenharmony_ci  if (processedSize)
348370b324cSopenharmony_ci    *processedSize = (UInt32)curSize;
349370b324cSopenharmony_ci  if (curSize != size)
350370b324cSopenharmony_ci  {
351370b324cSopenharmony_ci    // _overflow = true;
352370b324cSopenharmony_ci    return E_FAIL;
353370b324cSopenharmony_ci  }
354370b324cSopenharmony_ci  return S_OK;
355370b324cSopenharmony_ci}
356370b324cSopenharmony_ci
357370b324cSopenharmony_ci
358370b324cSopenharmony_ciZ7_CLASS_IMP_NOQIB_1(
359370b324cSopenharmony_ci  CCrcOutStream
360370b324cSopenharmony_ci  , ISequentialOutStream
361370b324cSopenharmony_ci)
362370b324cSopenharmony_cipublic:
363370b324cSopenharmony_ci  bool CalcCrc;
364370b324cSopenharmony_ci  UInt32 Crc;
365370b324cSopenharmony_ci  UInt64 Pos;
366370b324cSopenharmony_ci
367370b324cSopenharmony_ci  CCrcOutStream(): CalcCrc(true) {}
368370b324cSopenharmony_ci  void Init() { Crc = CRC_INIT_VAL; Pos = 0; }
369370b324cSopenharmony_ci  void Calc(const void *data, size_t size)
370370b324cSopenharmony_ci  {
371370b324cSopenharmony_ci    Crc = CrcUpdate(Crc, data, size);
372370b324cSopenharmony_ci  }
373370b324cSopenharmony_ci};
374370b324cSopenharmony_ci
375370b324cSopenharmony_ciZ7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
376370b324cSopenharmony_ci{
377370b324cSopenharmony_ci  if (CalcCrc)
378370b324cSopenharmony_ci    Calc(data, size);
379370b324cSopenharmony_ci  Pos += size;
380370b324cSopenharmony_ci  if (processedSize)
381370b324cSopenharmony_ci    *processedSize = size;
382370b324cSopenharmony_ci  return S_OK;
383370b324cSopenharmony_ci}
384370b324cSopenharmony_ci
385370b324cSopenharmony_ci// #include "../../../../C/My_sys_time.h"
386370b324cSopenharmony_ci
387370b324cSopenharmony_cistatic UInt64 GetTimeCount()
388370b324cSopenharmony_ci{
389370b324cSopenharmony_ci  #ifdef USE_POSIX_TIME
390370b324cSopenharmony_ci  #ifdef USE_POSIX_TIME2
391370b324cSopenharmony_ci  timeval v;
392370b324cSopenharmony_ci  if (gettimeofday(&v, NULL) == 0)
393370b324cSopenharmony_ci    return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec;
394370b324cSopenharmony_ci  return (UInt64)time(NULL) * 1000000;
395370b324cSopenharmony_ci  #else
396370b324cSopenharmony_ci  return time(NULL);
397370b324cSopenharmony_ci  #endif
398370b324cSopenharmony_ci  #else
399370b324cSopenharmony_ci  LARGE_INTEGER value;
400370b324cSopenharmony_ci  if (::QueryPerformanceCounter(&value))
401370b324cSopenharmony_ci    return (UInt64)value.QuadPart;
402370b324cSopenharmony_ci  return GetTickCount();
403370b324cSopenharmony_ci  #endif
404370b324cSopenharmony_ci}
405370b324cSopenharmony_ci
406370b324cSopenharmony_cistatic UInt64 GetFreq()
407370b324cSopenharmony_ci{
408370b324cSopenharmony_ci  #ifdef USE_POSIX_TIME
409370b324cSopenharmony_ci  #ifdef USE_POSIX_TIME2
410370b324cSopenharmony_ci  return 1000000;
411370b324cSopenharmony_ci  #else
412370b324cSopenharmony_ci  return 1;
413370b324cSopenharmony_ci  #endif
414370b324cSopenharmony_ci  #else
415370b324cSopenharmony_ci  LARGE_INTEGER value;
416370b324cSopenharmony_ci  if (::QueryPerformanceFrequency(&value))
417370b324cSopenharmony_ci    return (UInt64)value.QuadPart;
418370b324cSopenharmony_ci  return 1000;
419370b324cSopenharmony_ci  #endif
420370b324cSopenharmony_ci}
421370b324cSopenharmony_ci
422370b324cSopenharmony_ci
423370b324cSopenharmony_ci#ifdef USE_POSIX_TIME
424370b324cSopenharmony_ci
425370b324cSopenharmony_cistruct CUserTime
426370b324cSopenharmony_ci{
427370b324cSopenharmony_ci  UInt64 Sum;
428370b324cSopenharmony_ci  clock_t Prev;
429370b324cSopenharmony_ci
430370b324cSopenharmony_ci  void Init()
431370b324cSopenharmony_ci  {
432370b324cSopenharmony_ci    // Prev = clock();
433370b324cSopenharmony_ci    Sum = 0;
434370b324cSopenharmony_ci    Prev = 0;
435370b324cSopenharmony_ci    Update();
436370b324cSopenharmony_ci    Sum = 0;
437370b324cSopenharmony_ci  }
438370b324cSopenharmony_ci
439370b324cSopenharmony_ci  void Update()
440370b324cSopenharmony_ci  {
441370b324cSopenharmony_ci    tms t;
442370b324cSopenharmony_ci    /* clock_t res = */ times(&t);
443370b324cSopenharmony_ci    clock_t newVal = t.tms_utime + t.tms_stime;
444370b324cSopenharmony_ci    Sum += (UInt64)(newVal - Prev);
445370b324cSopenharmony_ci    Prev = newVal;
446370b324cSopenharmony_ci
447370b324cSopenharmony_ci    /*
448370b324cSopenharmony_ci    clock_t v = clock();
449370b324cSopenharmony_ci    if (v != -1)
450370b324cSopenharmony_ci    {
451370b324cSopenharmony_ci      Sum += v - Prev;
452370b324cSopenharmony_ci      Prev = v;
453370b324cSopenharmony_ci    }
454370b324cSopenharmony_ci    */
455370b324cSopenharmony_ci  }
456370b324cSopenharmony_ci  UInt64 GetUserTime()
457370b324cSopenharmony_ci  {
458370b324cSopenharmony_ci    Update();
459370b324cSopenharmony_ci    return Sum;
460370b324cSopenharmony_ci  }
461370b324cSopenharmony_ci};
462370b324cSopenharmony_ci
463370b324cSopenharmony_ci#else
464370b324cSopenharmony_ci
465370b324cSopenharmony_ci
466370b324cSopenharmony_cistruct CUserTime
467370b324cSopenharmony_ci{
468370b324cSopenharmony_ci  bool UseTick;
469370b324cSopenharmony_ci  DWORD Prev_Tick;
470370b324cSopenharmony_ci  UInt64 Prev;
471370b324cSopenharmony_ci  UInt64 Sum;
472370b324cSopenharmony_ci
473370b324cSopenharmony_ci  void Init()
474370b324cSopenharmony_ci  {
475370b324cSopenharmony_ci    UseTick = false;
476370b324cSopenharmony_ci    Prev_Tick = 0;
477370b324cSopenharmony_ci    Prev = 0;
478370b324cSopenharmony_ci    Sum = 0;
479370b324cSopenharmony_ci    Update();
480370b324cSopenharmony_ci    Sum = 0;
481370b324cSopenharmony_ci  }
482370b324cSopenharmony_ci  UInt64 GetUserTime()
483370b324cSopenharmony_ci  {
484370b324cSopenharmony_ci    Update();
485370b324cSopenharmony_ci    return Sum;
486370b324cSopenharmony_ci  }
487370b324cSopenharmony_ci  void Update();
488370b324cSopenharmony_ci};
489370b324cSopenharmony_ci
490370b324cSopenharmony_cistatic inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
491370b324cSopenharmony_ci
492370b324cSopenharmony_civoid CUserTime::Update()
493370b324cSopenharmony_ci{
494370b324cSopenharmony_ci  DWORD new_Tick = GetTickCount();
495370b324cSopenharmony_ci  FILETIME creationTime, exitTime, kernelTime, userTime;
496370b324cSopenharmony_ci  if (!UseTick &&
497370b324cSopenharmony_ci      #ifdef UNDER_CE
498370b324cSopenharmony_ci        ::GetThreadTimes(::GetCurrentThread()
499370b324cSopenharmony_ci      #else
500370b324cSopenharmony_ci        ::GetProcessTimes(::GetCurrentProcess()
501370b324cSopenharmony_ci      #endif
502370b324cSopenharmony_ci      , &creationTime, &exitTime, &kernelTime, &userTime))
503370b324cSopenharmony_ci  {
504370b324cSopenharmony_ci    UInt64 newVal = GetTime64(userTime) + GetTime64(kernelTime);
505370b324cSopenharmony_ci    Sum += newVal - Prev;
506370b324cSopenharmony_ci    Prev = newVal;
507370b324cSopenharmony_ci  }
508370b324cSopenharmony_ci  else
509370b324cSopenharmony_ci  {
510370b324cSopenharmony_ci    UseTick = true;
511370b324cSopenharmony_ci    Sum += (UInt64)(new_Tick - (DWORD)Prev_Tick) * 10000;
512370b324cSopenharmony_ci  }
513370b324cSopenharmony_ci  Prev_Tick = new_Tick;
514370b324cSopenharmony_ci}
515370b324cSopenharmony_ci
516370b324cSopenharmony_ci
517370b324cSopenharmony_ci#endif
518370b324cSopenharmony_ci
519370b324cSopenharmony_cistatic UInt64 GetUserFreq()
520370b324cSopenharmony_ci{
521370b324cSopenharmony_ci  #ifdef USE_POSIX_TIME
522370b324cSopenharmony_ci  // return CLOCKS_PER_SEC;
523370b324cSopenharmony_ci  return (UInt64)sysconf(_SC_CLK_TCK);
524370b324cSopenharmony_ci  #else
525370b324cSopenharmony_ci  return 10000000;
526370b324cSopenharmony_ci  #endif
527370b324cSopenharmony_ci}
528370b324cSopenharmony_ci
529370b324cSopenharmony_ciclass CBenchProgressStatus Z7_final
530370b324cSopenharmony_ci{
531370b324cSopenharmony_ci  #ifndef Z7_ST
532370b324cSopenharmony_ci  NSynchronization::CCriticalSection CS;
533370b324cSopenharmony_ci  #endif
534370b324cSopenharmony_cipublic:
535370b324cSopenharmony_ci  HRESULT Res;
536370b324cSopenharmony_ci  bool EncodeMode;
537370b324cSopenharmony_ci  void SetResult(HRESULT res)
538370b324cSopenharmony_ci  {
539370b324cSopenharmony_ci    #ifndef Z7_ST
540370b324cSopenharmony_ci    NSynchronization::CCriticalSectionLock lock(CS);
541370b324cSopenharmony_ci    #endif
542370b324cSopenharmony_ci    Res = res;
543370b324cSopenharmony_ci  }
544370b324cSopenharmony_ci  HRESULT GetResult()
545370b324cSopenharmony_ci  {
546370b324cSopenharmony_ci    #ifndef Z7_ST
547370b324cSopenharmony_ci    NSynchronization::CCriticalSectionLock lock(CS);
548370b324cSopenharmony_ci    #endif
549370b324cSopenharmony_ci    return Res;
550370b324cSopenharmony_ci  }
551370b324cSopenharmony_ci};
552370b324cSopenharmony_ci
553370b324cSopenharmony_cistruct CBenchInfoCalc
554370b324cSopenharmony_ci{
555370b324cSopenharmony_ci  CBenchInfo BenchInfo;
556370b324cSopenharmony_ci  CUserTime UserTime;
557370b324cSopenharmony_ci
558370b324cSopenharmony_ci  void SetStartTime();
559370b324cSopenharmony_ci  void SetFinishTime(CBenchInfo &dest);
560370b324cSopenharmony_ci};
561370b324cSopenharmony_ci
562370b324cSopenharmony_civoid CBenchInfoCalc::SetStartTime()
563370b324cSopenharmony_ci{
564370b324cSopenharmony_ci  BenchInfo.GlobalFreq = GetFreq();
565370b324cSopenharmony_ci  BenchInfo.UserFreq = GetUserFreq();
566370b324cSopenharmony_ci  BenchInfo.GlobalTime = ::GetTimeCount();
567370b324cSopenharmony_ci  BenchInfo.UserTime = 0;
568370b324cSopenharmony_ci  UserTime.Init();
569370b324cSopenharmony_ci}
570370b324cSopenharmony_ci
571370b324cSopenharmony_civoid CBenchInfoCalc::SetFinishTime(CBenchInfo &dest)
572370b324cSopenharmony_ci{
573370b324cSopenharmony_ci  dest = BenchInfo;
574370b324cSopenharmony_ci  dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime;
575370b324cSopenharmony_ci  dest.UserTime = UserTime.GetUserTime();
576370b324cSopenharmony_ci}
577370b324cSopenharmony_ci
578370b324cSopenharmony_ciclass CBenchProgressInfo Z7_final:
579370b324cSopenharmony_ci  public ICompressProgressInfo,
580370b324cSopenharmony_ci  public CMyUnknownImp,
581370b324cSopenharmony_ci  public CBenchInfoCalc
582370b324cSopenharmony_ci{
583370b324cSopenharmony_ci  Z7_COM_UNKNOWN_IMP_0
584370b324cSopenharmony_ci  Z7_IFACE_COM7_IMP(ICompressProgressInfo)
585370b324cSopenharmony_cipublic:
586370b324cSopenharmony_ci  CBenchProgressStatus *Status;
587370b324cSopenharmony_ci  IBenchCallback *Callback;
588370b324cSopenharmony_ci
589370b324cSopenharmony_ci  CBenchProgressInfo(): Callback(NULL) {}
590370b324cSopenharmony_ci};
591370b324cSopenharmony_ci
592370b324cSopenharmony_ci
593370b324cSopenharmony_ciZ7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
594370b324cSopenharmony_ci{
595370b324cSopenharmony_ci  HRESULT res = Status->GetResult();
596370b324cSopenharmony_ci  if (res != S_OK)
597370b324cSopenharmony_ci    return res;
598370b324cSopenharmony_ci  if (!Callback)
599370b324cSopenharmony_ci    return res;
600370b324cSopenharmony_ci
601370b324cSopenharmony_ci  /*
602370b324cSopenharmony_ci  static UInt64 inSizePrev = 0;
603370b324cSopenharmony_ci  static UInt64 outSizePrev = 0;
604370b324cSopenharmony_ci  UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0;
605370b324cSopenharmony_ci  if (inSize)   { val1 = *inSize;  delta1 = val1 - inSizePrev;  inSizePrev  = val1; }
606370b324cSopenharmony_ci  if (outSize)  { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2;  }
607370b324cSopenharmony_ci  UInt64 percents = delta2 * 1000;
608370b324cSopenharmony_ci  if (delta1 != 0)
609370b324cSopenharmony_ci    percents /= delta1;
610370b324cSopenharmony_ci  printf("=== %7d %7d     %7d %7d  ratio = %4d\n",
611370b324cSopenharmony_ci      (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10),
612370b324cSopenharmony_ci      (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10),
613370b324cSopenharmony_ci      (unsigned)percents);
614370b324cSopenharmony_ci  */
615370b324cSopenharmony_ci
616370b324cSopenharmony_ci  CBenchInfo info;
617370b324cSopenharmony_ci  SetFinishTime(info);
618370b324cSopenharmony_ci  if (Status->EncodeMode)
619370b324cSopenharmony_ci  {
620370b324cSopenharmony_ci    info.UnpackSize = BenchInfo.UnpackSize + *inSize;
621370b324cSopenharmony_ci    info.PackSize = BenchInfo.PackSize + *outSize;
622370b324cSopenharmony_ci    res = Callback->SetEncodeResult(info, false);
623370b324cSopenharmony_ci  }
624370b324cSopenharmony_ci  else
625370b324cSopenharmony_ci  {
626370b324cSopenharmony_ci    info.PackSize = BenchInfo.PackSize + *inSize;
627370b324cSopenharmony_ci    info.UnpackSize = BenchInfo.UnpackSize + *outSize;
628370b324cSopenharmony_ci    res = Callback->SetDecodeResult(info, false);
629370b324cSopenharmony_ci  }
630370b324cSopenharmony_ci  if (res != S_OK)
631370b324cSopenharmony_ci    Status->SetResult(res);
632370b324cSopenharmony_ci  return res;
633370b324cSopenharmony_ci}
634370b324cSopenharmony_ci
635370b324cSopenharmony_cistatic const unsigned kSubBits = 8;
636370b324cSopenharmony_ci
637370b324cSopenharmony_cistatic unsigned GetLogSize(UInt64 size)
638370b324cSopenharmony_ci{
639370b324cSopenharmony_ci  unsigned i = 0;
640370b324cSopenharmony_ci  for (;;)
641370b324cSopenharmony_ci  {
642370b324cSopenharmony_ci    i++;  size >>= 1;  if (size == 0) break;
643370b324cSopenharmony_ci  }
644370b324cSopenharmony_ci  return i;
645370b324cSopenharmony_ci}
646370b324cSopenharmony_ci
647370b324cSopenharmony_ci
648370b324cSopenharmony_cistatic UInt32 GetLogSize_Sub(UInt64 size)
649370b324cSopenharmony_ci{
650370b324cSopenharmony_ci  if (size <= 1)
651370b324cSopenharmony_ci    return 0;
652370b324cSopenharmony_ci  const unsigned i = GetLogSize(size) - 1;
653370b324cSopenharmony_ci  UInt32 v;
654370b324cSopenharmony_ci  if (i <= kSubBits)
655370b324cSopenharmony_ci    v = (UInt32)(size) << (kSubBits - i);
656370b324cSopenharmony_ci  else
657370b324cSopenharmony_ci    v = (UInt32)(size >> (i - kSubBits));
658370b324cSopenharmony_ci  return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1));
659370b324cSopenharmony_ci}
660370b324cSopenharmony_ci
661370b324cSopenharmony_ci
662370b324cSopenharmony_cistatic UInt64 Get_UInt64_from_double(double v)
663370b324cSopenharmony_ci{
664370b324cSopenharmony_ci  const UInt64 kMaxVal = (UInt64)1 << 62;
665370b324cSopenharmony_ci  if (v > (double)(Int64)kMaxVal)
666370b324cSopenharmony_ci    return kMaxVal;
667370b324cSopenharmony_ci  return (UInt64)v;
668370b324cSopenharmony_ci}
669370b324cSopenharmony_ci
670370b324cSopenharmony_cistatic UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d)
671370b324cSopenharmony_ci{
672370b324cSopenharmony_ci  if (d == 0)
673370b324cSopenharmony_ci    d = 1;
674370b324cSopenharmony_ci  const double v =
675370b324cSopenharmony_ci      (double)(Int64)m1 *
676370b324cSopenharmony_ci      (double)(Int64)m2 /
677370b324cSopenharmony_ci      (double)(Int64)d;
678370b324cSopenharmony_ci  return Get_UInt64_from_double(v);
679370b324cSopenharmony_ci  /*
680370b324cSopenharmony_ci  unsigned n1 = GetLogSize(m1);
681370b324cSopenharmony_ci  unsigned n2 = GetLogSize(m2);
682370b324cSopenharmony_ci  while (n1 + n2 > 64)
683370b324cSopenharmony_ci  {
684370b324cSopenharmony_ci    if (n1 >= n2)
685370b324cSopenharmony_ci    {
686370b324cSopenharmony_ci      m1 >>= 1;
687370b324cSopenharmony_ci      n1--;
688370b324cSopenharmony_ci    }
689370b324cSopenharmony_ci    else
690370b324cSopenharmony_ci    {
691370b324cSopenharmony_ci      m2 >>= 1;
692370b324cSopenharmony_ci      n2--;
693370b324cSopenharmony_ci    }
694370b324cSopenharmony_ci    d >>= 1;
695370b324cSopenharmony_ci  }
696370b324cSopenharmony_ci
697370b324cSopenharmony_ci  if (d == 0)
698370b324cSopenharmony_ci    d = 1;
699370b324cSopenharmony_ci  return m1 * m2 / d;
700370b324cSopenharmony_ci  */
701370b324cSopenharmony_ci}
702370b324cSopenharmony_ci
703370b324cSopenharmony_ci
704370b324cSopenharmony_ciUInt64 CBenchInfo::GetUsage() const
705370b324cSopenharmony_ci{
706370b324cSopenharmony_ci  UInt64 userTime = UserTime;
707370b324cSopenharmony_ci  UInt64 userFreq = UserFreq;
708370b324cSopenharmony_ci  UInt64 globalTime = GlobalTime;
709370b324cSopenharmony_ci  UInt64 globalFreq = GlobalFreq;
710370b324cSopenharmony_ci
711370b324cSopenharmony_ci  if (userFreq == 0)
712370b324cSopenharmony_ci    userFreq = 1;
713370b324cSopenharmony_ci  if (globalTime == 0)
714370b324cSopenharmony_ci    globalTime = 1;
715370b324cSopenharmony_ci
716370b324cSopenharmony_ci  const double v =
717370b324cSopenharmony_ci        ((double)(Int64)userTime / (double)(Int64)userFreq)
718370b324cSopenharmony_ci      * ((double)(Int64)globalFreq / (double)(Int64)globalTime)
719370b324cSopenharmony_ci      * (double)(Int64)kBenchmarkUsageMult;
720370b324cSopenharmony_ci  return Get_UInt64_from_double(v);
721370b324cSopenharmony_ci  /*
722370b324cSopenharmony_ci  return MyMultDiv64(
723370b324cSopenharmony_ci        MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq),
724370b324cSopenharmony_ci        globalFreq, globalTime);
725370b324cSopenharmony_ci  */
726370b324cSopenharmony_ci}
727370b324cSopenharmony_ci
728370b324cSopenharmony_ci
729370b324cSopenharmony_ciUInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
730370b324cSopenharmony_ci{
731370b324cSopenharmony_ci  if (UserTime == 0)
732370b324cSopenharmony_ci  {
733370b324cSopenharmony_ci    return 0;
734370b324cSopenharmony_ci    // userTime = 1;
735370b324cSopenharmony_ci  }
736370b324cSopenharmony_ci  UInt64 globalFreq = GlobalFreq;
737370b324cSopenharmony_ci  if (globalFreq == 0)
738370b324cSopenharmony_ci    globalFreq = 1;
739370b324cSopenharmony_ci
740370b324cSopenharmony_ci  const double v =
741370b324cSopenharmony_ci        ((double)(Int64)GlobalTime / (double)(Int64)globalFreq)
742370b324cSopenharmony_ci      * ((double)(Int64)UserFreq  / (double)(Int64)UserTime)
743370b324cSopenharmony_ci      * (double)(Int64)rating;
744370b324cSopenharmony_ci  return Get_UInt64_from_double(v);
745370b324cSopenharmony_ci  /*
746370b324cSopenharmony_ci  return MyMultDiv64(
747370b324cSopenharmony_ci        MyMultDiv64(rating, UserFreq, UserTime),
748370b324cSopenharmony_ci        GlobalTime, globalFreq);
749370b324cSopenharmony_ci  */
750370b324cSopenharmony_ci}
751370b324cSopenharmony_ci
752370b324cSopenharmony_ci
753370b324cSopenharmony_ciUInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const
754370b324cSopenharmony_ci{
755370b324cSopenharmony_ci  return MyMultDiv64(numUnits, GlobalFreq, GlobalTime);
756370b324cSopenharmony_ci}
757370b324cSopenharmony_ci
758370b324cSopenharmony_cistatic UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity)
759370b324cSopenharmony_ci{
760370b324cSopenharmony_ci  return complexity >= 0 ?
761370b324cSopenharmony_ci      size * (UInt32)complexity :
762370b324cSopenharmony_ci      size / (UInt32)(-complexity);
763370b324cSopenharmony_ci}
764370b324cSopenharmony_ci
765370b324cSopenharmony_cistruct CBenchProps
766370b324cSopenharmony_ci{
767370b324cSopenharmony_ci  bool LzmaRatingMode;
768370b324cSopenharmony_ci
769370b324cSopenharmony_ci  Int32 EncComplex;
770370b324cSopenharmony_ci  Int32 DecComplexCompr;
771370b324cSopenharmony_ci  Int32 DecComplexUnc;
772370b324cSopenharmony_ci
773370b324cSopenharmony_ci  unsigned KeySize;
774370b324cSopenharmony_ci
775370b324cSopenharmony_ci  CBenchProps():
776370b324cSopenharmony_ci      LzmaRatingMode(false),
777370b324cSopenharmony_ci      KeySize(0)
778370b324cSopenharmony_ci    {}
779370b324cSopenharmony_ci
780370b324cSopenharmony_ci  void SetLzmaCompexity();
781370b324cSopenharmony_ci
782370b324cSopenharmony_ci  UInt64 GetNumCommands_Enc(UInt64 unpackSize) const
783370b324cSopenharmony_ci  {
784370b324cSopenharmony_ci    const UInt32 kMinSize = 100;
785370b324cSopenharmony_ci    if (unpackSize < kMinSize)
786370b324cSopenharmony_ci      unpackSize = kMinSize;
787370b324cSopenharmony_ci    return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex);
788370b324cSopenharmony_ci  }
789370b324cSopenharmony_ci
790370b324cSopenharmony_ci  UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const
791370b324cSopenharmony_ci  {
792370b324cSopenharmony_ci    return
793370b324cSopenharmony_ci        GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) +
794370b324cSopenharmony_ci        GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc);
795370b324cSopenharmony_ci  }
796370b324cSopenharmony_ci
797370b324cSopenharmony_ci  UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const;
798370b324cSopenharmony_ci  UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const;
799370b324cSopenharmony_ci};
800370b324cSopenharmony_ci
801370b324cSopenharmony_civoid CBenchProps::SetLzmaCompexity()
802370b324cSopenharmony_ci{
803370b324cSopenharmony_ci  EncComplex = 1200;
804370b324cSopenharmony_ci  DecComplexUnc = 4;
805370b324cSopenharmony_ci  DecComplexCompr = 190;
806370b324cSopenharmony_ci  LzmaRatingMode = true;
807370b324cSopenharmony_ci}
808370b324cSopenharmony_ci
809370b324cSopenharmony_ciUInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const
810370b324cSopenharmony_ci{
811370b324cSopenharmony_ci  if (dictSize < (1 << kBenchMinDicLogSize))
812370b324cSopenharmony_ci    dictSize = (1 << kBenchMinDicLogSize);
813370b324cSopenharmony_ci  Int32 encComplex = EncComplex;
814370b324cSopenharmony_ci  if (LzmaRatingMode)
815370b324cSopenharmony_ci  {
816370b324cSopenharmony_ci    /*
817370b324cSopenharmony_ci    for (UInt64 uu = 0; uu < (UInt64)0xf << 60;)
818370b324cSopenharmony_ci    {
819370b324cSopenharmony_ci      unsigned rr = GetLogSize_Sub(uu);
820370b324cSopenharmony_ci      printf("\n%16I64x , log = %4x", uu, rr);
821370b324cSopenharmony_ci      uu += 1;
822370b324cSopenharmony_ci      uu += uu / 50;
823370b324cSopenharmony_ci    }
824370b324cSopenharmony_ci    */
825370b324cSopenharmony_ci    // throw 1;
826370b324cSopenharmony_ci    const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits);
827370b324cSopenharmony_ci    encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
828370b324cSopenharmony_ci  }
829370b324cSopenharmony_ci  const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex);
830370b324cSopenharmony_ci  return MyMultDiv64(numCommands, freq, elapsedTime);
831370b324cSopenharmony_ci}
832370b324cSopenharmony_ci
833370b324cSopenharmony_ciUInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const
834370b324cSopenharmony_ci{
835370b324cSopenharmony_ci  const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations;
836370b324cSopenharmony_ci  return MyMultDiv64(numCommands, freq, elapsedTime);
837370b324cSopenharmony_ci}
838370b324cSopenharmony_ci
839370b324cSopenharmony_ci
840370b324cSopenharmony_ci
841370b324cSopenharmony_ciUInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const
842370b324cSopenharmony_ci{
843370b324cSopenharmony_ci  CBenchProps props;
844370b324cSopenharmony_ci  props.SetLzmaCompexity();
845370b324cSopenharmony_ci  return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations);
846370b324cSopenharmony_ci}
847370b324cSopenharmony_ci
848370b324cSopenharmony_ciUInt64 CBenchInfo::GetRating_LzmaDec() const
849370b324cSopenharmony_ci{
850370b324cSopenharmony_ci  CBenchProps props;
851370b324cSopenharmony_ci  props.SetLzmaCompexity();
852370b324cSopenharmony_ci  return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations);
853370b324cSopenharmony_ci}
854370b324cSopenharmony_ci
855370b324cSopenharmony_ci
856370b324cSopenharmony_ci#ifndef Z7_ST
857370b324cSopenharmony_ci
858370b324cSopenharmony_ci#define NUM_CPU_LEVELS_MAX 3
859370b324cSopenharmony_ci
860370b324cSopenharmony_cistruct CAffinityMode
861370b324cSopenharmony_ci{
862370b324cSopenharmony_ci  unsigned NumBundleThreads;
863370b324cSopenharmony_ci  unsigned NumLevels;
864370b324cSopenharmony_ci  unsigned NumCoreThreads;
865370b324cSopenharmony_ci  unsigned NumCores;
866370b324cSopenharmony_ci  // unsigned DivideNum;
867370b324cSopenharmony_ci  UInt32 Sizes[NUM_CPU_LEVELS_MAX];
868370b324cSopenharmony_ci
869370b324cSopenharmony_ci  void SetLevels(unsigned numCores, unsigned numCoreThreads);
870370b324cSopenharmony_ci  DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const;
871370b324cSopenharmony_ci  bool NeedAffinity() const { return NumBundleThreads != 0; }
872370b324cSopenharmony_ci
873370b324cSopenharmony_ci  WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const
874370b324cSopenharmony_ci  {
875370b324cSopenharmony_ci    if (NeedAffinity())
876370b324cSopenharmony_ci    {
877370b324cSopenharmony_ci      CCpuSet cpuSet;
878370b324cSopenharmony_ci      GetAffinityMask(bundleIndex, &cpuSet);
879370b324cSopenharmony_ci      return thread.Create_With_CpuSet(startAddress, parameter, &cpuSet);
880370b324cSopenharmony_ci    }
881370b324cSopenharmony_ci    return thread.Create(startAddress, parameter);
882370b324cSopenharmony_ci  }
883370b324cSopenharmony_ci
884370b324cSopenharmony_ci  CAffinityMode():
885370b324cSopenharmony_ci    NumBundleThreads(0),
886370b324cSopenharmony_ci    NumLevels(0),
887370b324cSopenharmony_ci    NumCoreThreads(1)
888370b324cSopenharmony_ci    // DivideNum(1)
889370b324cSopenharmony_ci    {}
890370b324cSopenharmony_ci};
891370b324cSopenharmony_ci
892370b324cSopenharmony_civoid CAffinityMode::SetLevels(unsigned numCores, unsigned numCoreThreads)
893370b324cSopenharmony_ci{
894370b324cSopenharmony_ci  NumCores = numCores;
895370b324cSopenharmony_ci  NumCoreThreads = numCoreThreads;
896370b324cSopenharmony_ci  NumLevels = 0;
897370b324cSopenharmony_ci  if (numCoreThreads == 0 || numCores == 0 || numCores % numCoreThreads != 0)
898370b324cSopenharmony_ci    return;
899370b324cSopenharmony_ci  UInt32 c = numCores / numCoreThreads;
900370b324cSopenharmony_ci  UInt32 c2 = 1;
901370b324cSopenharmony_ci  while ((c & 1) == 0)
902370b324cSopenharmony_ci  {
903370b324cSopenharmony_ci    c >>= 1;
904370b324cSopenharmony_ci    c2 <<= 1;
905370b324cSopenharmony_ci  }
906370b324cSopenharmony_ci  if (c2 != 1)
907370b324cSopenharmony_ci    Sizes[NumLevels++] = c2;
908370b324cSopenharmony_ci  if (c != 1)
909370b324cSopenharmony_ci    Sizes[NumLevels++] = c;
910370b324cSopenharmony_ci  if (numCoreThreads != 1)
911370b324cSopenharmony_ci    Sizes[NumLevels++] = numCoreThreads;
912370b324cSopenharmony_ci  if (NumLevels == 0)
913370b324cSopenharmony_ci    Sizes[NumLevels++] = 1;
914370b324cSopenharmony_ci
915370b324cSopenharmony_ci  /*
916370b324cSopenharmony_ci  printf("\n Cores:");
917370b324cSopenharmony_ci  for (unsigned i = 0; i < NumLevels; i++)
918370b324cSopenharmony_ci  {
919370b324cSopenharmony_ci    printf(" %d", Sizes[i]);
920370b324cSopenharmony_ci  }
921370b324cSopenharmony_ci  printf("\n");
922370b324cSopenharmony_ci  */
923370b324cSopenharmony_ci}
924370b324cSopenharmony_ci
925370b324cSopenharmony_ci
926370b324cSopenharmony_ciDWORD_PTR CAffinityMode::GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const
927370b324cSopenharmony_ci{
928370b324cSopenharmony_ci  CpuSet_Zero(cpuSet);
929370b324cSopenharmony_ci
930370b324cSopenharmony_ci  if (NumLevels == 0)
931370b324cSopenharmony_ci    return 0;
932370b324cSopenharmony_ci
933370b324cSopenharmony_ci  // printf("\n%2d", bundleIndex);
934370b324cSopenharmony_ci
935370b324cSopenharmony_ci  /*
936370b324cSopenharmony_ci  UInt32 low = 0;
937370b324cSopenharmony_ci  if (DivideNum != 1)
938370b324cSopenharmony_ci  {
939370b324cSopenharmony_ci    low = bundleIndex % DivideNum;
940370b324cSopenharmony_ci    bundleIndex /= DivideNum;
941370b324cSopenharmony_ci  }
942370b324cSopenharmony_ci  */
943370b324cSopenharmony_ci
944370b324cSopenharmony_ci  UInt32 numGroups = NumCores / NumBundleThreads;
945370b324cSopenharmony_ci  UInt32 m = bundleIndex % numGroups;
946370b324cSopenharmony_ci  UInt32 v = 0;
947370b324cSopenharmony_ci  for (unsigned i = 0; i < NumLevels; i++)
948370b324cSopenharmony_ci  {
949370b324cSopenharmony_ci    UInt32 size = Sizes[i];
950370b324cSopenharmony_ci    while ((size & 1) == 0)
951370b324cSopenharmony_ci    {
952370b324cSopenharmony_ci      v *= 2;
953370b324cSopenharmony_ci      v |= (m & 1);
954370b324cSopenharmony_ci      m >>= 1;
955370b324cSopenharmony_ci      size >>= 1;
956370b324cSopenharmony_ci    }
957370b324cSopenharmony_ci    v *= size;
958370b324cSopenharmony_ci    v += m % size;
959370b324cSopenharmony_ci    m /= size;
960370b324cSopenharmony_ci  }
961370b324cSopenharmony_ci
962370b324cSopenharmony_ci  // UInt32 nb = NumBundleThreads / DivideNum;
963370b324cSopenharmony_ci  UInt32 nb = NumBundleThreads;
964370b324cSopenharmony_ci
965370b324cSopenharmony_ci  DWORD_PTR mask = ((DWORD_PTR)1 << nb) - 1;
966370b324cSopenharmony_ci  // v += low;
967370b324cSopenharmony_ci  mask <<= v;
968370b324cSopenharmony_ci
969370b324cSopenharmony_ci  // printf(" %2d %8x \n ", v, (unsigned)mask);
970370b324cSopenharmony_ci  #ifdef _WIN32
971370b324cSopenharmony_ci    *cpuSet = mask;
972370b324cSopenharmony_ci  #else
973370b324cSopenharmony_ci  {
974370b324cSopenharmony_ci    for (unsigned k = 0; k < nb; k++)
975370b324cSopenharmony_ci      CpuSet_Set(cpuSet, v + k);
976370b324cSopenharmony_ci  }
977370b324cSopenharmony_ci  #endif
978370b324cSopenharmony_ci
979370b324cSopenharmony_ci  return mask;
980370b324cSopenharmony_ci}
981370b324cSopenharmony_ci
982370b324cSopenharmony_ci
983370b324cSopenharmony_cistruct CBenchSyncCommon
984370b324cSopenharmony_ci{
985370b324cSopenharmony_ci  bool ExitMode;
986370b324cSopenharmony_ci  NSynchronization::CManualResetEvent StartEvent;
987370b324cSopenharmony_ci
988370b324cSopenharmony_ci  CBenchSyncCommon(): ExitMode(false) {}
989370b324cSopenharmony_ci};
990370b324cSopenharmony_ci
991370b324cSopenharmony_ci#endif
992370b324cSopenharmony_ci
993370b324cSopenharmony_ci
994370b324cSopenharmony_ci
995370b324cSopenharmony_cienum E_CheckCrcMode
996370b324cSopenharmony_ci{
997370b324cSopenharmony_ci  k_CheckCrcMode_Never = 0,
998370b324cSopenharmony_ci  k_CheckCrcMode_Always = 1,
999370b324cSopenharmony_ci  k_CheckCrcMode_FirstPass = 2
1000370b324cSopenharmony_ci};
1001370b324cSopenharmony_ci
1002370b324cSopenharmony_ciclass CEncoderInfo;
1003370b324cSopenharmony_ci
1004370b324cSopenharmony_ciclass CEncoderInfo Z7_final
1005370b324cSopenharmony_ci{
1006370b324cSopenharmony_ci  Z7_CLASS_NO_COPY(CEncoderInfo)
1007370b324cSopenharmony_ci
1008370b324cSopenharmony_cipublic:
1009370b324cSopenharmony_ci
1010370b324cSopenharmony_ci  #ifndef Z7_ST
1011370b324cSopenharmony_ci  NWindows::CThread thread[2];
1012370b324cSopenharmony_ci  NSynchronization::CManualResetEvent ReadyEvent;
1013370b324cSopenharmony_ci  UInt32 NumDecoderSubThreads;
1014370b324cSopenharmony_ci  CBenchSyncCommon *Common;
1015370b324cSopenharmony_ci  UInt32 EncoderIndex;
1016370b324cSopenharmony_ci  UInt32 NumEncoderInternalThreads;
1017370b324cSopenharmony_ci  CAffinityMode AffinityMode;
1018370b324cSopenharmony_ci  bool IsGlobalMtMode; // if more than one benchmark encoder threads
1019370b324cSopenharmony_ci  #endif
1020370b324cSopenharmony_ci
1021370b324cSopenharmony_ci  CMyComPtr<ICompressCoder> _encoder;
1022370b324cSopenharmony_ci  CMyComPtr<ICompressFilter> _encoderFilter;
1023370b324cSopenharmony_ci  CBenchProgressInfo *progressInfoSpec[2];
1024370b324cSopenharmony_ci  CMyComPtr<ICompressProgressInfo> progressInfo[2];
1025370b324cSopenharmony_ci  UInt64 NumIterations;
1026370b324cSopenharmony_ci
1027370b324cSopenharmony_ci  UInt32 Salt;
1028370b324cSopenharmony_ci
1029370b324cSopenharmony_ci  #ifdef USE_ALLOCA
1030370b324cSopenharmony_ci  size_t AllocaSize;
1031370b324cSopenharmony_ci  #endif
1032370b324cSopenharmony_ci
1033370b324cSopenharmony_ci  unsigned KeySize;
1034370b324cSopenharmony_ci  Byte _key[32];
1035370b324cSopenharmony_ci  Byte _iv[16];
1036370b324cSopenharmony_ci
1037370b324cSopenharmony_ci  HRESULT Set_Key_and_IV(ICryptoProperties *cp)
1038370b324cSopenharmony_ci  {
1039370b324cSopenharmony_ci    RINOK(cp->SetKey(_key, KeySize))
1040370b324cSopenharmony_ci    return cp->SetInitVector(_iv, sizeof(_iv));
1041370b324cSopenharmony_ci  }
1042370b324cSopenharmony_ci
1043370b324cSopenharmony_ci  Byte _psw[16];
1044370b324cSopenharmony_ci
1045370b324cSopenharmony_ci  bool CheckCrc_Enc;    /* = 1, if we want to check packed data crcs after each pass
1046370b324cSopenharmony_ci                                used for filter and usual coders */
1047370b324cSopenharmony_ci  bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass
1048370b324cSopenharmony_ci                                used only for filter */
1049370b324cSopenharmony_ci  E_CheckCrcMode CheckCrcMode_Dec;
1050370b324cSopenharmony_ci
1051370b324cSopenharmony_ci  struct CDecoderInfo
1052370b324cSopenharmony_ci  {
1053370b324cSopenharmony_ci    CEncoderInfo *Encoder;
1054370b324cSopenharmony_ci    UInt32 DecoderIndex;
1055370b324cSopenharmony_ci    bool CallbackMode;
1056370b324cSopenharmony_ci
1057370b324cSopenharmony_ci    #ifdef USE_ALLOCA
1058370b324cSopenharmony_ci    size_t AllocaSize;
1059370b324cSopenharmony_ci    #endif
1060370b324cSopenharmony_ci  };
1061370b324cSopenharmony_ci  CDecoderInfo decodersInfo[2];
1062370b324cSopenharmony_ci
1063370b324cSopenharmony_ci  CMyComPtr<ICompressCoder> _decoders[2];
1064370b324cSopenharmony_ci  CMyComPtr<ICompressFilter> _decoderFilter;
1065370b324cSopenharmony_ci
1066370b324cSopenharmony_ci  HRESULT Results[2];
1067370b324cSopenharmony_ci  CBenchmarkOutStream *outStreamSpec;
1068370b324cSopenharmony_ci  CMyComPtr<ISequentialOutStream> outStream;
1069370b324cSopenharmony_ci  IBenchCallback *callback;
1070370b324cSopenharmony_ci  IBenchPrintCallback *printCallback;
1071370b324cSopenharmony_ci  UInt32 crc;
1072370b324cSopenharmony_ci  size_t kBufferSize;
1073370b324cSopenharmony_ci  size_t compressedSize;
1074370b324cSopenharmony_ci  const Byte *uncompressedDataPtr;
1075370b324cSopenharmony_ci
1076370b324cSopenharmony_ci  const Byte *fileData;
1077370b324cSopenharmony_ci  CBenchRandomGenerator rg;
1078370b324cSopenharmony_ci
1079370b324cSopenharmony_ci  CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!!
1080370b324cSopenharmony_ci
1081370b324cSopenharmony_ci  // CBenchmarkOutStream *propStreamSpec;
1082370b324cSopenharmony_ci  Byte propsData[kMaxMethodPropSize];
1083370b324cSopenharmony_ci  CBufPtrSeqOutStream *propStreamSpec;
1084370b324cSopenharmony_ci  CMyComPtr<ISequentialOutStream> propStream;
1085370b324cSopenharmony_ci
1086370b324cSopenharmony_ci  unsigned generateDictBits;
1087370b324cSopenharmony_ci  COneMethodInfo _method;
1088370b324cSopenharmony_ci
1089370b324cSopenharmony_ci  // for decode
1090370b324cSopenharmony_ci  size_t _uncompressedDataSize;
1091370b324cSopenharmony_ci
1092370b324cSopenharmony_ci  HRESULT Generate();
1093370b324cSopenharmony_ci  HRESULT Encode();
1094370b324cSopenharmony_ci  HRESULT Decode(UInt32 decoderIndex);
1095370b324cSopenharmony_ci
1096370b324cSopenharmony_ci  CEncoderInfo():
1097370b324cSopenharmony_ci    #ifndef Z7_ST
1098370b324cSopenharmony_ci    Common(NULL),
1099370b324cSopenharmony_ci    IsGlobalMtMode(true),
1100370b324cSopenharmony_ci    #endif
1101370b324cSopenharmony_ci    Salt(0),
1102370b324cSopenharmony_ci    KeySize(0),
1103370b324cSopenharmony_ci    CheckCrc_Enc(true),
1104370b324cSopenharmony_ci    UseRealData_Enc(true),
1105370b324cSopenharmony_ci    CheckCrcMode_Dec(k_CheckCrcMode_Always),
1106370b324cSopenharmony_ci    outStreamSpec(NULL),
1107370b324cSopenharmony_ci    callback(NULL),
1108370b324cSopenharmony_ci    printCallback(NULL),
1109370b324cSopenharmony_ci    fileData(NULL),
1110370b324cSopenharmony_ci    propStreamSpec(NULL)
1111370b324cSopenharmony_ci    {}
1112370b324cSopenharmony_ci
1113370b324cSopenharmony_ci  #ifndef Z7_ST
1114370b324cSopenharmony_ci
1115370b324cSopenharmony_ci  static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
1116370b324cSopenharmony_ci  {
1117370b324cSopenharmony_ci    HRESULT res;
1118370b324cSopenharmony_ci    CEncoderInfo *encoder = (CEncoderInfo *)param;
1119370b324cSopenharmony_ci    try
1120370b324cSopenharmony_ci    {
1121370b324cSopenharmony_ci      #ifdef USE_ALLOCA
1122370b324cSopenharmony_ci      alloca(encoder->AllocaSize);
1123370b324cSopenharmony_ci      #endif
1124370b324cSopenharmony_ci
1125370b324cSopenharmony_ci      res = encoder->Encode();
1126370b324cSopenharmony_ci    }
1127370b324cSopenharmony_ci    catch(...)
1128370b324cSopenharmony_ci    {
1129370b324cSopenharmony_ci      res = E_FAIL;
1130370b324cSopenharmony_ci    }
1131370b324cSopenharmony_ci    encoder->Results[0] = res;
1132370b324cSopenharmony_ci    if (res != S_OK)
1133370b324cSopenharmony_ci      encoder->progressInfoSpec[0]->Status->SetResult(res);
1134370b324cSopenharmony_ci    encoder->ReadyEvent.Set();
1135370b324cSopenharmony_ci    return THREAD_FUNC_RET_ZERO;
1136370b324cSopenharmony_ci  }
1137370b324cSopenharmony_ci
1138370b324cSopenharmony_ci  static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
1139370b324cSopenharmony_ci  {
1140370b324cSopenharmony_ci    CDecoderInfo *decoder = (CDecoderInfo *)param;
1141370b324cSopenharmony_ci
1142370b324cSopenharmony_ci    #ifdef USE_ALLOCA
1143370b324cSopenharmony_ci    alloca(decoder->AllocaSize);
1144370b324cSopenharmony_ci    #endif
1145370b324cSopenharmony_ci
1146370b324cSopenharmony_ci    CEncoderInfo *encoder = decoder->Encoder;
1147370b324cSopenharmony_ci    encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
1148370b324cSopenharmony_ci    return THREAD_FUNC_RET_ZERO;
1149370b324cSopenharmony_ci  }
1150370b324cSopenharmony_ci
1151370b324cSopenharmony_ci  HRESULT CreateEncoderThread()
1152370b324cSopenharmony_ci  {
1153370b324cSopenharmony_ci    WRes res = 0;
1154370b324cSopenharmony_ci    if (!ReadyEvent.IsCreated())
1155370b324cSopenharmony_ci      res = ReadyEvent.Create();
1156370b324cSopenharmony_ci    if (res == 0)
1157370b324cSopenharmony_ci      res = AffinityMode.CreateThread_WithAffinity(thread[0], EncodeThreadFunction, this,
1158370b324cSopenharmony_ci          EncoderIndex);
1159370b324cSopenharmony_ci    return HRESULT_FROM_WIN32(res);
1160370b324cSopenharmony_ci  }
1161370b324cSopenharmony_ci
1162370b324cSopenharmony_ci  HRESULT CreateDecoderThread(unsigned index, bool callbackMode
1163370b324cSopenharmony_ci      #ifdef USE_ALLOCA
1164370b324cSopenharmony_ci      , size_t allocaSize
1165370b324cSopenharmony_ci      #endif
1166370b324cSopenharmony_ci      )
1167370b324cSopenharmony_ci  {
1168370b324cSopenharmony_ci    CDecoderInfo &decoder = decodersInfo[index];
1169370b324cSopenharmony_ci    decoder.DecoderIndex = index;
1170370b324cSopenharmony_ci    decoder.Encoder = this;
1171370b324cSopenharmony_ci
1172370b324cSopenharmony_ci    #ifdef USE_ALLOCA
1173370b324cSopenharmony_ci    decoder.AllocaSize = allocaSize;
1174370b324cSopenharmony_ci    #endif
1175370b324cSopenharmony_ci
1176370b324cSopenharmony_ci    decoder.CallbackMode = callbackMode;
1177370b324cSopenharmony_ci
1178370b324cSopenharmony_ci    WRes res = AffinityMode.CreateThread_WithAffinity(thread[index], DecodeThreadFunction, &decoder,
1179370b324cSopenharmony_ci        // EncoderIndex * NumEncoderInternalThreads + index
1180370b324cSopenharmony_ci        EncoderIndex
1181370b324cSopenharmony_ci        );
1182370b324cSopenharmony_ci
1183370b324cSopenharmony_ci    return HRESULT_FROM_WIN32(res);
1184370b324cSopenharmony_ci  }
1185370b324cSopenharmony_ci
1186370b324cSopenharmony_ci  #endif
1187370b324cSopenharmony_ci};
1188370b324cSopenharmony_ci
1189370b324cSopenharmony_ci
1190370b324cSopenharmony_ci
1191370b324cSopenharmony_ci
1192370b324cSopenharmony_cistatic size_t GetBenchCompressedSize(size_t bufferSize)
1193370b324cSopenharmony_ci{
1194370b324cSopenharmony_ci  return kCompressedAdditionalSize + bufferSize + bufferSize / 16;
1195370b324cSopenharmony_ci  // kBufferSize / 2;
1196370b324cSopenharmony_ci}
1197370b324cSopenharmony_ci
1198370b324cSopenharmony_ci
1199370b324cSopenharmony_ciHRESULT CEncoderInfo::Generate()
1200370b324cSopenharmony_ci{
1201370b324cSopenharmony_ci  const COneMethodInfo &method = _method;
1202370b324cSopenharmony_ci
1203370b324cSopenharmony_ci  // we need extra space, if input data is already compressed
1204370b324cSopenharmony_ci  const size_t kCompressedBufferSize = _encoderFilter ?
1205370b324cSopenharmony_ci      kBufferSize :
1206370b324cSopenharmony_ci      GetBenchCompressedSize(kBufferSize);
1207370b324cSopenharmony_ci
1208370b324cSopenharmony_ci  if (kCompressedBufferSize < kBufferSize)
1209370b324cSopenharmony_ci    return E_FAIL;
1210370b324cSopenharmony_ci
1211370b324cSopenharmony_ci  uncompressedDataPtr = fileData;
1212370b324cSopenharmony_ci  if (fileData)
1213370b324cSopenharmony_ci  {
1214370b324cSopenharmony_ci    #if !defined(Z7_ST)
1215370b324cSopenharmony_ci    if (IsGlobalMtMode)
1216370b324cSopenharmony_ci    {
1217370b324cSopenharmony_ci      /* we copy the data to local buffer of thread to eliminate
1218370b324cSopenharmony_ci         using of shared buffer by different threads */
1219370b324cSopenharmony_ci      ALLOC_WITH_HRESULT(&rg, kBufferSize)
1220370b324cSopenharmony_ci      memcpy((Byte *)rg, fileData, kBufferSize);
1221370b324cSopenharmony_ci      uncompressedDataPtr = (const Byte *)rg;
1222370b324cSopenharmony_ci    }
1223370b324cSopenharmony_ci    #endif
1224370b324cSopenharmony_ci  }
1225370b324cSopenharmony_ci  else
1226370b324cSopenharmony_ci  {
1227370b324cSopenharmony_ci    ALLOC_WITH_HRESULT(&rg, kBufferSize)
1228370b324cSopenharmony_ci    // DWORD ttt = GetTickCount();
1229370b324cSopenharmony_ci    if (generateDictBits == 0)
1230370b324cSopenharmony_ci      rg.GenerateSimpleRandom(Salt);
1231370b324cSopenharmony_ci    else
1232370b324cSopenharmony_ci    {
1233370b324cSopenharmony_ci      if (generateDictBits >= sizeof(size_t) * 8
1234370b324cSopenharmony_ci          && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1)))
1235370b324cSopenharmony_ci        return E_INVALIDARG;
1236370b324cSopenharmony_ci      rg.GenerateLz(generateDictBits, Salt);
1237370b324cSopenharmony_ci      // return E_ABORT; // for debug
1238370b324cSopenharmony_ci    }
1239370b324cSopenharmony_ci    // printf("\n%d\n            ", GetTickCount() - ttt);
1240370b324cSopenharmony_ci
1241370b324cSopenharmony_ci    crc = CrcCalc((const Byte *)rg, rg.Size());
1242370b324cSopenharmony_ci    uncompressedDataPtr = (const Byte *)rg;
1243370b324cSopenharmony_ci  }
1244370b324cSopenharmony_ci
1245370b324cSopenharmony_ci  if (!outStream)
1246370b324cSopenharmony_ci  {
1247370b324cSopenharmony_ci    outStreamSpec = new CBenchmarkOutStream;
1248370b324cSopenharmony_ci    outStream = outStreamSpec;
1249370b324cSopenharmony_ci  }
1250370b324cSopenharmony_ci
1251370b324cSopenharmony_ci  ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize)
1252370b324cSopenharmony_ci
1253370b324cSopenharmony_ci  if (_encoderFilter)
1254370b324cSopenharmony_ci  {
1255370b324cSopenharmony_ci    /* we try to reduce the number of memcpy() in main encoding loop.
1256370b324cSopenharmony_ci       so we copy data to temp buffers here */
1257370b324cSopenharmony_ci    ALLOC_WITH_HRESULT(&rgCopy, kBufferSize)
1258370b324cSopenharmony_ci    memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize);
1259370b324cSopenharmony_ci    memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize);
1260370b324cSopenharmony_ci  }
1261370b324cSopenharmony_ci
1262370b324cSopenharmony_ci  if (!propStream)
1263370b324cSopenharmony_ci  {
1264370b324cSopenharmony_ci    propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream;
1265370b324cSopenharmony_ci    propStream = propStreamSpec;
1266370b324cSopenharmony_ci  }
1267370b324cSopenharmony_ci  // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize);
1268370b324cSopenharmony_ci  // propStreamSpec->Init(true, false);
1269370b324cSopenharmony_ci  propStreamSpec->Init(propsData, sizeof(propsData));
1270370b324cSopenharmony_ci
1271370b324cSopenharmony_ci
1272370b324cSopenharmony_ci  CMyComPtr<IUnknown> coder;
1273370b324cSopenharmony_ci  if (_encoderFilter)
1274370b324cSopenharmony_ci    coder = _encoderFilter;
1275370b324cSopenharmony_ci  else
1276370b324cSopenharmony_ci    coder = _encoder;
1277370b324cSopenharmony_ci  {
1278370b324cSopenharmony_ci    CMyComPtr<ICompressSetCoderProperties> scp;
1279370b324cSopenharmony_ci    coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
1280370b324cSopenharmony_ci    if (scp)
1281370b324cSopenharmony_ci    {
1282370b324cSopenharmony_ci      const UInt64 reduceSize = kBufferSize;
1283370b324cSopenharmony_ci
1284370b324cSopenharmony_ci      /* in posix new thread uses same affinity as parent thread,
1285370b324cSopenharmony_ci         so we don't need to send affinity to coder in posix */
1286370b324cSopenharmony_ci      UInt64 affMask;
1287370b324cSopenharmony_ci      #if !defined(Z7_ST) && defined(_WIN32)
1288370b324cSopenharmony_ci      {
1289370b324cSopenharmony_ci        CCpuSet cpuSet;
1290370b324cSopenharmony_ci        affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet);
1291370b324cSopenharmony_ci      }
1292370b324cSopenharmony_ci      #else
1293370b324cSopenharmony_ci        affMask = 0;
1294370b324cSopenharmony_ci      #endif
1295370b324cSopenharmony_ci      // affMask <<= 3; // debug line: to test no affinity in coder;
1296370b324cSopenharmony_ci      // affMask = 0;
1297370b324cSopenharmony_ci
1298370b324cSopenharmony_ci      RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, (affMask != 0 ? &affMask : NULL)))
1299370b324cSopenharmony_ci    }
1300370b324cSopenharmony_ci    else
1301370b324cSopenharmony_ci    {
1302370b324cSopenharmony_ci      if (method.AreThereNonOptionalProps())
1303370b324cSopenharmony_ci        return E_INVALIDARG;
1304370b324cSopenharmony_ci    }
1305370b324cSopenharmony_ci
1306370b324cSopenharmony_ci    CMyComPtr<ICompressWriteCoderProperties> writeCoderProps;
1307370b324cSopenharmony_ci    coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
1308370b324cSopenharmony_ci    if (writeCoderProps)
1309370b324cSopenharmony_ci    {
1310370b324cSopenharmony_ci      RINOK(writeCoderProps->WriteCoderProperties(propStream))
1311370b324cSopenharmony_ci    }
1312370b324cSopenharmony_ci
1313370b324cSopenharmony_ci    {
1314370b324cSopenharmony_ci      CMyComPtr<ICryptoSetPassword> sp;
1315370b324cSopenharmony_ci      coder.QueryInterface(IID_ICryptoSetPassword, &sp);
1316370b324cSopenharmony_ci      if (sp)
1317370b324cSopenharmony_ci      {
1318370b324cSopenharmony_ci        RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
1319370b324cSopenharmony_ci
1320370b324cSopenharmony_ci        // we must call encoding one time to calculate password key for key cache.
1321370b324cSopenharmony_ci        // it must be after WriteCoderProperties!
1322370b324cSopenharmony_ci        Byte temp[16];
1323370b324cSopenharmony_ci        memset(temp, 0, sizeof(temp));
1324370b324cSopenharmony_ci
1325370b324cSopenharmony_ci        if (_encoderFilter)
1326370b324cSopenharmony_ci        {
1327370b324cSopenharmony_ci          _encoderFilter->Init();
1328370b324cSopenharmony_ci          _encoderFilter->Filter(temp, sizeof(temp));
1329370b324cSopenharmony_ci        }
1330370b324cSopenharmony_ci        else
1331370b324cSopenharmony_ci        {
1332370b324cSopenharmony_ci          CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1333370b324cSopenharmony_ci          CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1334370b324cSopenharmony_ci          inStreamSpec->Init(temp, sizeof(temp));
1335370b324cSopenharmony_ci
1336370b324cSopenharmony_ci          CCrcOutStream *crcStreamSpec = new CCrcOutStream;
1337370b324cSopenharmony_ci          CMyComPtr<ISequentialOutStream> crcStream = crcStreamSpec;
1338370b324cSopenharmony_ci          crcStreamSpec->Init();
1339370b324cSopenharmony_ci
1340370b324cSopenharmony_ci          RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL))
1341370b324cSopenharmony_ci        }
1342370b324cSopenharmony_ci      }
1343370b324cSopenharmony_ci    }
1344370b324cSopenharmony_ci  }
1345370b324cSopenharmony_ci
1346370b324cSopenharmony_ci  return S_OK;
1347370b324cSopenharmony_ci}
1348370b324cSopenharmony_ci
1349370b324cSopenharmony_ci
1350370b324cSopenharmony_cistatic void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc)
1351370b324cSopenharmony_ci{
1352370b324cSopenharmony_ci  while (size != 0)
1353370b324cSopenharmony_ci  {
1354370b324cSopenharmony_ci    UInt32 cur = crc ? 1 << 17 : 1 << 24;
1355370b324cSopenharmony_ci    if (cur > size)
1356370b324cSopenharmony_ci      cur = (UInt32)size;
1357370b324cSopenharmony_ci    UInt32 processed = filter->Filter(data, cur);
1358370b324cSopenharmony_ci    /* if (processed > size) (in AES filter), we must fill last block with zeros.
1359370b324cSopenharmony_ci       but it is not important for benchmark. So we just copy that data without filtering.
1360370b324cSopenharmony_ci       if (processed == 0) then filter can't process more  */
1361370b324cSopenharmony_ci    if (processed > size || processed == 0)
1362370b324cSopenharmony_ci      processed = (UInt32)size;
1363370b324cSopenharmony_ci    if (crc)
1364370b324cSopenharmony_ci      *crc = CrcUpdate(*crc, data, processed);
1365370b324cSopenharmony_ci    data += processed;
1366370b324cSopenharmony_ci    size -= processed;
1367370b324cSopenharmony_ci  }
1368370b324cSopenharmony_ci}
1369370b324cSopenharmony_ci
1370370b324cSopenharmony_ci
1371370b324cSopenharmony_ciHRESULT CEncoderInfo::Encode()
1372370b324cSopenharmony_ci{
1373370b324cSopenharmony_ci  // printf("\nCEncoderInfo::Generate\n");
1374370b324cSopenharmony_ci
1375370b324cSopenharmony_ci  RINOK(Generate())
1376370b324cSopenharmony_ci
1377370b324cSopenharmony_ci  // printf("\n2222\n");
1378370b324cSopenharmony_ci
1379370b324cSopenharmony_ci  #ifndef Z7_ST
1380370b324cSopenharmony_ci  if (Common)
1381370b324cSopenharmony_ci  {
1382370b324cSopenharmony_ci    Results[0] = S_OK;
1383370b324cSopenharmony_ci    WRes wres = ReadyEvent.Set();
1384370b324cSopenharmony_ci    if (wres == 0)
1385370b324cSopenharmony_ci      wres = Common->StartEvent.Lock();
1386370b324cSopenharmony_ci    if (wres != 0)
1387370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
1388370b324cSopenharmony_ci    if (Common->ExitMode)
1389370b324cSopenharmony_ci      return S_OK;
1390370b324cSopenharmony_ci  }
1391370b324cSopenharmony_ci  else
1392370b324cSopenharmony_ci  #endif
1393370b324cSopenharmony_ci  {
1394370b324cSopenharmony_ci    CBenchProgressInfo *bpi = progressInfoSpec[0];
1395370b324cSopenharmony_ci    bpi->SetStartTime();
1396370b324cSopenharmony_ci  }
1397370b324cSopenharmony_ci
1398370b324cSopenharmony_ci
1399370b324cSopenharmony_ci  CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
1400370b324cSopenharmony_ci  bi.UnpackSize = 0;
1401370b324cSopenharmony_ci  bi.PackSize = 0;
1402370b324cSopenharmony_ci  CMyComPtr<ICryptoProperties> cp;
1403370b324cSopenharmony_ci  CMyComPtr<IUnknown> coder;
1404370b324cSopenharmony_ci  if (_encoderFilter)
1405370b324cSopenharmony_ci    coder = _encoderFilter;
1406370b324cSopenharmony_ci  else
1407370b324cSopenharmony_ci    coder = _encoder;
1408370b324cSopenharmony_ci  coder.QueryInterface(IID_ICryptoProperties, &cp);
1409370b324cSopenharmony_ci  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1410370b324cSopenharmony_ci  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1411370b324cSopenharmony_ci
1412370b324cSopenharmony_ci  if (cp)
1413370b324cSopenharmony_ci  {
1414370b324cSopenharmony_ci    RINOK(Set_Key_and_IV(cp))
1415370b324cSopenharmony_ci  }
1416370b324cSopenharmony_ci
1417370b324cSopenharmony_ci  compressedSize = 0;
1418370b324cSopenharmony_ci  if (_encoderFilter)
1419370b324cSopenharmony_ci    compressedSize = kBufferSize;
1420370b324cSopenharmony_ci
1421370b324cSopenharmony_ci  // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec;
1422370b324cSopenharmony_ci  UInt64 prev = 0;
1423370b324cSopenharmony_ci
1424370b324cSopenharmony_ci  const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF);
1425370b324cSopenharmony_ci  const bool useCrc = (mask < NumIterations);
1426370b324cSopenharmony_ci  bool crcPrev_defined = false;
1427370b324cSopenharmony_ci  UInt32 crcPrev = 0;
1428370b324cSopenharmony_ci
1429370b324cSopenharmony_ci  bool useRealData_Enc = UseRealData_Enc;
1430370b324cSopenharmony_ci  bool data_Was_Changed = false;
1431370b324cSopenharmony_ci  if (useRealData_Enc)
1432370b324cSopenharmony_ci  {
1433370b324cSopenharmony_ci    /* we want memcpy() for each iteration including first iteration.
1434370b324cSopenharmony_ci       So results will be equal for different number of iterations */
1435370b324cSopenharmony_ci    data_Was_Changed = true;
1436370b324cSopenharmony_ci  }
1437370b324cSopenharmony_ci
1438370b324cSopenharmony_ci  const UInt64 numIterations = NumIterations;
1439370b324cSopenharmony_ci  UInt64 i = numIterations;
1440370b324cSopenharmony_ci    // printCallback->NewLine();
1441370b324cSopenharmony_ci
1442370b324cSopenharmony_ci  while (i != 0)
1443370b324cSopenharmony_ci  {
1444370b324cSopenharmony_ci    i--;
1445370b324cSopenharmony_ci    if (printCallback && bi.UnpackSize - prev >= (1 << 26))
1446370b324cSopenharmony_ci    {
1447370b324cSopenharmony_ci      prev = bi.UnpackSize;
1448370b324cSopenharmony_ci      RINOK(printCallback->CheckBreak())
1449370b324cSopenharmony_ci    }
1450370b324cSopenharmony_ci
1451370b324cSopenharmony_ci    /*
1452370b324cSopenharmony_ci    CBenchInfo info;
1453370b324cSopenharmony_ci    progressInfoSpec[0]->SetStartTime();
1454370b324cSopenharmony_ci    */
1455370b324cSopenharmony_ci
1456370b324cSopenharmony_ci    bool calcCrc = false;
1457370b324cSopenharmony_ci    if (useCrc)
1458370b324cSopenharmony_ci      calcCrc = (((UInt32)i & mask) == 0);
1459370b324cSopenharmony_ci
1460370b324cSopenharmony_ci    if (_encoderFilter)
1461370b324cSopenharmony_ci    {
1462370b324cSopenharmony_ci      Byte *filterData = rgCopy;
1463370b324cSopenharmony_ci      if (i == numIterations - 1 || calcCrc || useRealData_Enc)
1464370b324cSopenharmony_ci      {
1465370b324cSopenharmony_ci        filterData = (Byte *)*outStreamSpec;
1466370b324cSopenharmony_ci        if (data_Was_Changed)
1467370b324cSopenharmony_ci          memcpy(filterData, uncompressedDataPtr, kBufferSize);
1468370b324cSopenharmony_ci        data_Was_Changed = true;
1469370b324cSopenharmony_ci      }
1470370b324cSopenharmony_ci      _encoderFilter->Init();
1471370b324cSopenharmony_ci      if (calcCrc)
1472370b324cSopenharmony_ci        outStreamSpec->InitCrc();
1473370b324cSopenharmony_ci      My_FilterBench(_encoderFilter, filterData, kBufferSize,
1474370b324cSopenharmony_ci          calcCrc ? &outStreamSpec->Crc : NULL);
1475370b324cSopenharmony_ci    }
1476370b324cSopenharmony_ci    else
1477370b324cSopenharmony_ci    {
1478370b324cSopenharmony_ci      outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations
1479370b324cSopenharmony_ci      inStreamSpec->Init(uncompressedDataPtr, kBufferSize);
1480370b324cSopenharmony_ci      RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]))
1481370b324cSopenharmony_ci      if (!inStreamSpec->WasFinished())
1482370b324cSopenharmony_ci        return E_FAIL;
1483370b324cSopenharmony_ci      if (compressedSize != outStreamSpec->Pos)
1484370b324cSopenharmony_ci      {
1485370b324cSopenharmony_ci        if (compressedSize != 0)
1486370b324cSopenharmony_ci          return E_FAIL;
1487370b324cSopenharmony_ci        compressedSize = outStreamSpec->Pos;
1488370b324cSopenharmony_ci      }
1489370b324cSopenharmony_ci    }
1490370b324cSopenharmony_ci
1491370b324cSopenharmony_ci    // outStreamSpec->Print();
1492370b324cSopenharmony_ci
1493370b324cSopenharmony_ci    if (calcCrc)
1494370b324cSopenharmony_ci    {
1495370b324cSopenharmony_ci      const UInt32 crc2 = CRC_GET_DIGEST(outStreamSpec->Crc);
1496370b324cSopenharmony_ci      if (crcPrev_defined && crcPrev != crc2)
1497370b324cSopenharmony_ci        return E_FAIL;
1498370b324cSopenharmony_ci      crcPrev = crc2;
1499370b324cSopenharmony_ci      crcPrev_defined = true;
1500370b324cSopenharmony_ci    }
1501370b324cSopenharmony_ci
1502370b324cSopenharmony_ci    bi.UnpackSize += kBufferSize;
1503370b324cSopenharmony_ci    bi.PackSize += compressedSize;
1504370b324cSopenharmony_ci
1505370b324cSopenharmony_ci    /*
1506370b324cSopenharmony_ci    {
1507370b324cSopenharmony_ci      progressInfoSpec[0]->SetFinishTime(info);
1508370b324cSopenharmony_ci      info.UnpackSize = 0;
1509370b324cSopenharmony_ci      info.PackSize = 0;
1510370b324cSopenharmony_ci      info.NumIterations = 1;
1511370b324cSopenharmony_ci
1512370b324cSopenharmony_ci      info.UnpackSize = kBufferSize;
1513370b324cSopenharmony_ci      info.PackSize = compressedSize;
1514370b324cSopenharmony_ci      // printf("\n%7d\n", encoder.compressedSize);
1515370b324cSopenharmony_ci
1516370b324cSopenharmony_ci      RINOK(callback->SetEncodeResult(info, true))
1517370b324cSopenharmony_ci      printCallback->NewLine();
1518370b324cSopenharmony_ci    }
1519370b324cSopenharmony_ci    */
1520370b324cSopenharmony_ci
1521370b324cSopenharmony_ci  }
1522370b324cSopenharmony_ci
1523370b324cSopenharmony_ci  _encoder.Release();
1524370b324cSopenharmony_ci  _encoderFilter.Release();
1525370b324cSopenharmony_ci  return S_OK;
1526370b324cSopenharmony_ci}
1527370b324cSopenharmony_ci
1528370b324cSopenharmony_ci
1529370b324cSopenharmony_ciHRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
1530370b324cSopenharmony_ci{
1531370b324cSopenharmony_ci  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1532370b324cSopenharmony_ci  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1533370b324cSopenharmony_ci  CMyComPtr<ICompressCoder> &decoder = _decoders[decoderIndex];
1534370b324cSopenharmony_ci  CMyComPtr<IUnknown> coder;
1535370b324cSopenharmony_ci  if (_decoderFilter)
1536370b324cSopenharmony_ci  {
1537370b324cSopenharmony_ci    if (decoderIndex != 0)
1538370b324cSopenharmony_ci      return E_FAIL;
1539370b324cSopenharmony_ci    coder = _decoderFilter;
1540370b324cSopenharmony_ci  }
1541370b324cSopenharmony_ci  else
1542370b324cSopenharmony_ci    coder = decoder;
1543370b324cSopenharmony_ci
1544370b324cSopenharmony_ci  CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
1545370b324cSopenharmony_ci  coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
1546370b324cSopenharmony_ci  if (!setDecProps && propStreamSpec->GetPos() != 0)
1547370b324cSopenharmony_ci    return E_FAIL;
1548370b324cSopenharmony_ci
1549370b324cSopenharmony_ci  CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
1550370b324cSopenharmony_ci  CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
1551370b324cSopenharmony_ci
1552370b324cSopenharmony_ci  CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
1553370b324cSopenharmony_ci  pi->BenchInfo.UnpackSize = 0;
1554370b324cSopenharmony_ci  pi->BenchInfo.PackSize = 0;
1555370b324cSopenharmony_ci
1556370b324cSopenharmony_ci  #ifndef Z7_ST
1557370b324cSopenharmony_ci  {
1558370b324cSopenharmony_ci    CMyComPtr<ICompressSetCoderMt> setCoderMt;
1559370b324cSopenharmony_ci    coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
1560370b324cSopenharmony_ci    if (setCoderMt)
1561370b324cSopenharmony_ci    {
1562370b324cSopenharmony_ci      RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads))
1563370b324cSopenharmony_ci    }
1564370b324cSopenharmony_ci  }
1565370b324cSopenharmony_ci  #endif
1566370b324cSopenharmony_ci
1567370b324cSopenharmony_ci  CMyComPtr<ICompressSetCoderProperties> scp;
1568370b324cSopenharmony_ci  coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
1569370b324cSopenharmony_ci  if (scp)
1570370b324cSopenharmony_ci  {
1571370b324cSopenharmony_ci    const UInt64 reduceSize = _uncompressedDataSize;
1572370b324cSopenharmony_ci    RINOK(_method.SetCoderProps(scp, &reduceSize))
1573370b324cSopenharmony_ci  }
1574370b324cSopenharmony_ci
1575370b324cSopenharmony_ci  CMyComPtr<ICryptoProperties> cp;
1576370b324cSopenharmony_ci  coder.QueryInterface(IID_ICryptoProperties, &cp);
1577370b324cSopenharmony_ci
1578370b324cSopenharmony_ci  if (setDecProps)
1579370b324cSopenharmony_ci  {
1580370b324cSopenharmony_ci    RINOK(setDecProps->SetDecoderProperties2(
1581370b324cSopenharmony_ci        /* (const Byte *)*propStreamSpec, */
1582370b324cSopenharmony_ci        propsData,
1583370b324cSopenharmony_ci        (UInt32)propStreamSpec->GetPos()))
1584370b324cSopenharmony_ci  }
1585370b324cSopenharmony_ci
1586370b324cSopenharmony_ci  {
1587370b324cSopenharmony_ci    CMyComPtr<ICryptoSetPassword> sp;
1588370b324cSopenharmony_ci    coder.QueryInterface(IID_ICryptoSetPassword, &sp);
1589370b324cSopenharmony_ci    if (sp)
1590370b324cSopenharmony_ci    {
1591370b324cSopenharmony_ci      RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
1592370b324cSopenharmony_ci    }
1593370b324cSopenharmony_ci  }
1594370b324cSopenharmony_ci
1595370b324cSopenharmony_ci  UInt64 prev = 0;
1596370b324cSopenharmony_ci
1597370b324cSopenharmony_ci  if (cp)
1598370b324cSopenharmony_ci  {
1599370b324cSopenharmony_ci    RINOK(Set_Key_and_IV(cp))
1600370b324cSopenharmony_ci  }
1601370b324cSopenharmony_ci
1602370b324cSopenharmony_ci  CMyComPtr<ICompressSetFinishMode> setFinishMode;
1603370b324cSopenharmony_ci
1604370b324cSopenharmony_ci  if (_decoderFilter)
1605370b324cSopenharmony_ci  {
1606370b324cSopenharmony_ci    if (compressedSize > rgCopy.Size())
1607370b324cSopenharmony_ci      return E_FAIL;
1608370b324cSopenharmony_ci  }
1609370b324cSopenharmony_ci  else
1610370b324cSopenharmony_ci  {
1611370b324cSopenharmony_ci    decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
1612370b324cSopenharmony_ci  }
1613370b324cSopenharmony_ci
1614370b324cSopenharmony_ci  const UInt64 numIterations = NumIterations;
1615370b324cSopenharmony_ci  const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec;
1616370b324cSopenharmony_ci
1617370b324cSopenharmony_ci  for (UInt64 i = 0; i < numIterations; i++)
1618370b324cSopenharmony_ci  {
1619370b324cSopenharmony_ci    if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26))
1620370b324cSopenharmony_ci    {
1621370b324cSopenharmony_ci      RINOK(printCallback->CheckBreak())
1622370b324cSopenharmony_ci      prev = pi->BenchInfo.UnpackSize;
1623370b324cSopenharmony_ci    }
1624370b324cSopenharmony_ci
1625370b324cSopenharmony_ci    const UInt64 outSize = kBufferSize;
1626370b324cSopenharmony_ci    bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never);
1627370b324cSopenharmony_ci
1628370b324cSopenharmony_ci    crcOutStreamSpec->Init();
1629370b324cSopenharmony_ci
1630370b324cSopenharmony_ci    if (_decoderFilter)
1631370b324cSopenharmony_ci    {
1632370b324cSopenharmony_ci      Byte *filterData = (Byte *)*outStreamSpec;
1633370b324cSopenharmony_ci      if (calcCrc)
1634370b324cSopenharmony_ci      {
1635370b324cSopenharmony_ci        calcCrc = (i == 0);
1636370b324cSopenharmony_ci        if (checkCrcMode == k_CheckCrcMode_Always)
1637370b324cSopenharmony_ci        {
1638370b324cSopenharmony_ci          calcCrc = true;
1639370b324cSopenharmony_ci          memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize);
1640370b324cSopenharmony_ci          filterData = rgCopy;
1641370b324cSopenharmony_ci        }
1642370b324cSopenharmony_ci      }
1643370b324cSopenharmony_ci      _decoderFilter->Init();
1644370b324cSopenharmony_ci      My_FilterBench(_decoderFilter, filterData, compressedSize,
1645370b324cSopenharmony_ci          calcCrc ? &crcOutStreamSpec->Crc : NULL);
1646370b324cSopenharmony_ci    }
1647370b324cSopenharmony_ci    else
1648370b324cSopenharmony_ci    {
1649370b324cSopenharmony_ci      crcOutStreamSpec->CalcCrc = calcCrc;
1650370b324cSopenharmony_ci      inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize);
1651370b324cSopenharmony_ci
1652370b324cSopenharmony_ci      if (setFinishMode)
1653370b324cSopenharmony_ci      {
1654370b324cSopenharmony_ci        RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)))
1655370b324cSopenharmony_ci      }
1656370b324cSopenharmony_ci
1657370b324cSopenharmony_ci      RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex]))
1658370b324cSopenharmony_ci
1659370b324cSopenharmony_ci      if (setFinishMode)
1660370b324cSopenharmony_ci      {
1661370b324cSopenharmony_ci        if (!inStreamSpec->WasFinished())
1662370b324cSopenharmony_ci          return S_FALSE;
1663370b324cSopenharmony_ci
1664370b324cSopenharmony_ci        CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
1665370b324cSopenharmony_ci        decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
1666370b324cSopenharmony_ci
1667370b324cSopenharmony_ci        if (getInStreamProcessedSize)
1668370b324cSopenharmony_ci        {
1669370b324cSopenharmony_ci          UInt64 processed;
1670370b324cSopenharmony_ci          RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
1671370b324cSopenharmony_ci          if (processed != compressedSize)
1672370b324cSopenharmony_ci            return S_FALSE;
1673370b324cSopenharmony_ci        }
1674370b324cSopenharmony_ci      }
1675370b324cSopenharmony_ci
1676370b324cSopenharmony_ci      if (crcOutStreamSpec->Pos != outSize)
1677370b324cSopenharmony_ci        return S_FALSE;
1678370b324cSopenharmony_ci    }
1679370b324cSopenharmony_ci
1680370b324cSopenharmony_ci    if (calcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
1681370b324cSopenharmony_ci      return S_FALSE;
1682370b324cSopenharmony_ci
1683370b324cSopenharmony_ci    pi->BenchInfo.UnpackSize += kBufferSize;
1684370b324cSopenharmony_ci    pi->BenchInfo.PackSize += compressedSize;
1685370b324cSopenharmony_ci  }
1686370b324cSopenharmony_ci
1687370b324cSopenharmony_ci  decoder.Release();
1688370b324cSopenharmony_ci  _decoderFilter.Release();
1689370b324cSopenharmony_ci  return S_OK;
1690370b324cSopenharmony_ci}
1691370b324cSopenharmony_ci
1692370b324cSopenharmony_ci
1693370b324cSopenharmony_cistatic const UInt32 kNumThreadsMax = (1 << 12);
1694370b324cSopenharmony_ci
1695370b324cSopenharmony_cistruct CBenchEncoders
1696370b324cSopenharmony_ci{
1697370b324cSopenharmony_ci  CEncoderInfo *encoders;
1698370b324cSopenharmony_ci  CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
1699370b324cSopenharmony_ci  ~CBenchEncoders() { delete []encoders; }
1700370b324cSopenharmony_ci};
1701370b324cSopenharmony_ci
1702370b324cSopenharmony_ci
1703370b324cSopenharmony_cistatic UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
1704370b324cSopenharmony_ci{
1705370b324cSopenharmony_ci  if (numCommands < (1 << 4))
1706370b324cSopenharmony_ci    numCommands = (1 << 4);
1707370b324cSopenharmony_ci  UInt64 res = complexInCommands / numCommands;
1708370b324cSopenharmony_ci  return (res == 0 ? 1 : res);
1709370b324cSopenharmony_ci}
1710370b324cSopenharmony_ci
1711370b324cSopenharmony_ci
1712370b324cSopenharmony_ci
1713370b324cSopenharmony_ci#ifndef Z7_ST
1714370b324cSopenharmony_ci
1715370b324cSopenharmony_ci// ---------- CBenchThreadsFlusher ----------
1716370b324cSopenharmony_ci
1717370b324cSopenharmony_cistruct CBenchThreadsFlusher
1718370b324cSopenharmony_ci{
1719370b324cSopenharmony_ci  CBenchEncoders *EncodersSpec;
1720370b324cSopenharmony_ci  CBenchSyncCommon Common;
1721370b324cSopenharmony_ci  unsigned NumThreads;
1722370b324cSopenharmony_ci  bool NeedClose;
1723370b324cSopenharmony_ci
1724370b324cSopenharmony_ci  CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {}
1725370b324cSopenharmony_ci
1726370b324cSopenharmony_ci  ~CBenchThreadsFlusher()
1727370b324cSopenharmony_ci  {
1728370b324cSopenharmony_ci    StartAndWait(true);
1729370b324cSopenharmony_ci  }
1730370b324cSopenharmony_ci
1731370b324cSopenharmony_ci  WRes StartAndWait(bool exitMode = false);
1732370b324cSopenharmony_ci};
1733370b324cSopenharmony_ci
1734370b324cSopenharmony_ci
1735370b324cSopenharmony_ciWRes CBenchThreadsFlusher::StartAndWait(bool exitMode)
1736370b324cSopenharmony_ci{
1737370b324cSopenharmony_ci  if (!NeedClose)
1738370b324cSopenharmony_ci    return 0;
1739370b324cSopenharmony_ci
1740370b324cSopenharmony_ci  Common.ExitMode = exitMode;
1741370b324cSopenharmony_ci  WRes res = Common.StartEvent.Set();
1742370b324cSopenharmony_ci
1743370b324cSopenharmony_ci  for (unsigned i = 0; i < NumThreads; i++)
1744370b324cSopenharmony_ci  {
1745370b324cSopenharmony_ci    NWindows::CThread &t = EncodersSpec->encoders[i].thread[0];
1746370b324cSopenharmony_ci    if (t.IsCreated())
1747370b324cSopenharmony_ci    {
1748370b324cSopenharmony_ci      WRes res2 = t.Wait_Close();
1749370b324cSopenharmony_ci      if (res == 0)
1750370b324cSopenharmony_ci        res = res2;
1751370b324cSopenharmony_ci    }
1752370b324cSopenharmony_ci  }
1753370b324cSopenharmony_ci  NeedClose = false;
1754370b324cSopenharmony_ci  return res;
1755370b324cSopenharmony_ci}
1756370b324cSopenharmony_ci
1757370b324cSopenharmony_ci#endif // Z7_ST
1758370b324cSopenharmony_ci
1759370b324cSopenharmony_ci
1760370b324cSopenharmony_ci
1761370b324cSopenharmony_cistatic void SetPseudoRand(Byte *data, size_t size, UInt32 startValue)
1762370b324cSopenharmony_ci{
1763370b324cSopenharmony_ci  for (size_t i = 0; i < size; i++)
1764370b324cSopenharmony_ci  {
1765370b324cSopenharmony_ci    data[i] = (Byte)startValue;
1766370b324cSopenharmony_ci    startValue++;
1767370b324cSopenharmony_ci  }
1768370b324cSopenharmony_ci}
1769370b324cSopenharmony_ci
1770370b324cSopenharmony_ci
1771370b324cSopenharmony_ci
1772370b324cSopenharmony_cistatic HRESULT MethodBench(
1773370b324cSopenharmony_ci    DECL_EXTERNAL_CODECS_LOC_VARS
1774370b324cSopenharmony_ci    UInt64 complexInCommands,
1775370b324cSopenharmony_ci    #ifndef Z7_ST
1776370b324cSopenharmony_ci      bool oldLzmaBenchMode,
1777370b324cSopenharmony_ci      UInt32 numThreads,
1778370b324cSopenharmony_ci      const CAffinityMode *affinityMode,
1779370b324cSopenharmony_ci    #endif
1780370b324cSopenharmony_ci    const COneMethodInfo &method2,
1781370b324cSopenharmony_ci    size_t uncompressedDataSize,
1782370b324cSopenharmony_ci    const Byte *fileData,
1783370b324cSopenharmony_ci    unsigned generateDictBits,
1784370b324cSopenharmony_ci
1785370b324cSopenharmony_ci    IBenchPrintCallback *printCallback,
1786370b324cSopenharmony_ci    IBenchCallback *callback,
1787370b324cSopenharmony_ci    CBenchProps *benchProps)
1788370b324cSopenharmony_ci{
1789370b324cSopenharmony_ci  COneMethodInfo method = method2;
1790370b324cSopenharmony_ci  UInt64 methodId;
1791370b324cSopenharmony_ci  UInt32 numStreams;
1792370b324cSopenharmony_ci  bool isFilter;
1793370b324cSopenharmony_ci  const int codecIndex = FindMethod_Index(
1794370b324cSopenharmony_ci      EXTERNAL_CODECS_LOC_VARS
1795370b324cSopenharmony_ci      method.MethodName, true,
1796370b324cSopenharmony_ci      methodId, numStreams, isFilter);
1797370b324cSopenharmony_ci  if (codecIndex < 0)
1798370b324cSopenharmony_ci    return E_NOTIMPL;
1799370b324cSopenharmony_ci  if (numStreams != 1)
1800370b324cSopenharmony_ci    return E_INVALIDARG;
1801370b324cSopenharmony_ci
1802370b324cSopenharmony_ci  UInt32 numEncoderThreads = 1;
1803370b324cSopenharmony_ci  UInt32 numSubDecoderThreads = 1;
1804370b324cSopenharmony_ci
1805370b324cSopenharmony_ci  #ifndef Z7_ST
1806370b324cSopenharmony_ci    numEncoderThreads = numThreads;
1807370b324cSopenharmony_ci
1808370b324cSopenharmony_ci    if (oldLzmaBenchMode)
1809370b324cSopenharmony_ci    if (methodId == k_LZMA)
1810370b324cSopenharmony_ci    {
1811370b324cSopenharmony_ci      if (numThreads == 1 && method.Get_NumThreads() < 0)
1812370b324cSopenharmony_ci        method.AddProp_NumThreads(1);
1813370b324cSopenharmony_ci      const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads();
1814370b324cSopenharmony_ci      if (numThreads > 1 && numLzmaThreads > 1)
1815370b324cSopenharmony_ci      {
1816370b324cSopenharmony_ci        numEncoderThreads = (numThreads + 1) / 2; // 20.03
1817370b324cSopenharmony_ci        numSubDecoderThreads = 2;
1818370b324cSopenharmony_ci      }
1819370b324cSopenharmony_ci    }
1820370b324cSopenharmony_ci
1821370b324cSopenharmony_ci  const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity();
1822370b324cSopenharmony_ci
1823370b324cSopenharmony_ci  #endif
1824370b324cSopenharmony_ci
1825370b324cSopenharmony_ci  CBenchEncoders encodersSpec(numEncoderThreads);
1826370b324cSopenharmony_ci  CEncoderInfo *encoders = encodersSpec.encoders;
1827370b324cSopenharmony_ci
1828370b324cSopenharmony_ci  UInt32 i;
1829370b324cSopenharmony_ci
1830370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
1831370b324cSopenharmony_ci  {
1832370b324cSopenharmony_ci    CEncoderInfo &encoder = encoders[i];
1833370b324cSopenharmony_ci    encoder.callback = (i == 0) ? callback : NULL;
1834370b324cSopenharmony_ci    encoder.printCallback = printCallback;
1835370b324cSopenharmony_ci
1836370b324cSopenharmony_ci    #ifndef Z7_ST
1837370b324cSopenharmony_ci    encoder.EncoderIndex = i;
1838370b324cSopenharmony_ci    encoder.NumEncoderInternalThreads = numSubDecoderThreads;
1839370b324cSopenharmony_ci    encoder.AffinityMode = *affinityMode;
1840370b324cSopenharmony_ci
1841370b324cSopenharmony_ci    /*
1842370b324cSopenharmony_ci    if (numSubDecoderThreads > 1)
1843370b324cSopenharmony_ci    if (encoder.AffinityMode.NeedAffinity()
1844370b324cSopenharmony_ci        && encoder.AffinityMode.NumBundleThreads == 1)
1845370b324cSopenharmony_ci    {
1846370b324cSopenharmony_ci      // if old LZMA benchmark uses two threads in coder, we increase (NumBundleThreads) for old LZMA benchmark uses two threads instead of one
1847370b324cSopenharmony_ci      if (encoder.AffinityMode.NumBundleThreads * 2 <= encoder.AffinityMode.NumCores)
1848370b324cSopenharmony_ci        encoder.AffinityMode.NumBundleThreads *= 2;
1849370b324cSopenharmony_ci    }
1850370b324cSopenharmony_ci    */
1851370b324cSopenharmony_ci
1852370b324cSopenharmony_ci    #endif
1853370b324cSopenharmony_ci
1854370b324cSopenharmony_ci    {
1855370b324cSopenharmony_ci      CCreatedCoder cod;
1856370b324cSopenharmony_ci      RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod))
1857370b324cSopenharmony_ci      encoder._encoder = cod.Coder;
1858370b324cSopenharmony_ci      if (!encoder._encoder && !encoder._encoderFilter)
1859370b324cSopenharmony_ci        return E_NOTIMPL;
1860370b324cSopenharmony_ci    }
1861370b324cSopenharmony_ci
1862370b324cSopenharmony_ci    SetPseudoRand(encoder._iv,  sizeof(encoder._iv), 17);
1863370b324cSopenharmony_ci    SetPseudoRand(encoder._key, sizeof(encoder._key), 51);
1864370b324cSopenharmony_ci    SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123);
1865370b324cSopenharmony_ci
1866370b324cSopenharmony_ci    for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1867370b324cSopenharmony_ci    {
1868370b324cSopenharmony_ci      CCreatedCoder cod;
1869370b324cSopenharmony_ci      CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
1870370b324cSopenharmony_ci      RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod))
1871370b324cSopenharmony_ci      decoder = cod.Coder;
1872370b324cSopenharmony_ci      if (!encoder._decoderFilter && !decoder)
1873370b324cSopenharmony_ci        return E_NOTIMPL;
1874370b324cSopenharmony_ci    }
1875370b324cSopenharmony_ci
1876370b324cSopenharmony_ci    encoder.UseRealData_Enc =
1877370b324cSopenharmony_ci    encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30;
1878370b324cSopenharmony_ci
1879370b324cSopenharmony_ci    encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
1880370b324cSopenharmony_ci    if (benchProps->DecComplexCompr +
1881370b324cSopenharmony_ci        benchProps->DecComplexUnc <= 30)
1882370b324cSopenharmony_ci      encoder.CheckCrcMode_Dec =
1883370b324cSopenharmony_ci          k_CheckCrcMode_FirstPass; // for filters
1884370b324cSopenharmony_ci          // k_CheckCrcMode_Never; // for debug
1885370b324cSopenharmony_ci          // k_CheckCrcMode_Always; // for debug
1886370b324cSopenharmony_ci    if (fileData)
1887370b324cSopenharmony_ci    {
1888370b324cSopenharmony_ci      encoder.UseRealData_Enc = true;
1889370b324cSopenharmony_ci      encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
1890370b324cSopenharmony_ci    }
1891370b324cSopenharmony_ci  }
1892370b324cSopenharmony_ci
1893370b324cSopenharmony_ci  UInt32 crc = 0;
1894370b324cSopenharmony_ci  if (fileData)
1895370b324cSopenharmony_ci    crc = CrcCalc(fileData, uncompressedDataSize);
1896370b324cSopenharmony_ci
1897370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
1898370b324cSopenharmony_ci  {
1899370b324cSopenharmony_ci    CEncoderInfo &encoder = encoders[i];
1900370b324cSopenharmony_ci    encoder._method = method;
1901370b324cSopenharmony_ci    encoder.generateDictBits = generateDictBits;
1902370b324cSopenharmony_ci    encoder._uncompressedDataSize = uncompressedDataSize;
1903370b324cSopenharmony_ci    encoder.kBufferSize = uncompressedDataSize;
1904370b324cSopenharmony_ci    encoder.fileData = fileData;
1905370b324cSopenharmony_ci    encoder.crc = crc;
1906370b324cSopenharmony_ci  }
1907370b324cSopenharmony_ci
1908370b324cSopenharmony_ci  CBenchProgressStatus status;
1909370b324cSopenharmony_ci  status.Res = S_OK;
1910370b324cSopenharmony_ci  status.EncodeMode = true;
1911370b324cSopenharmony_ci
1912370b324cSopenharmony_ci  #ifndef Z7_ST
1913370b324cSopenharmony_ci  CBenchThreadsFlusher encoderFlusher;
1914370b324cSopenharmony_ci  if (mtEncMode)
1915370b324cSopenharmony_ci  {
1916370b324cSopenharmony_ci    WRes wres = encoderFlusher.Common.StartEvent.Create();
1917370b324cSopenharmony_ci    if (wres != 0)
1918370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
1919370b324cSopenharmony_ci    encoderFlusher.NumThreads = numEncoderThreads;
1920370b324cSopenharmony_ci    encoderFlusher.EncodersSpec = &encodersSpec;
1921370b324cSopenharmony_ci    encoderFlusher.NeedClose = true;
1922370b324cSopenharmony_ci  }
1923370b324cSopenharmony_ci  #endif
1924370b324cSopenharmony_ci
1925370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
1926370b324cSopenharmony_ci  {
1927370b324cSopenharmony_ci    CEncoderInfo &encoder = encoders[i];
1928370b324cSopenharmony_ci    encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands);
1929370b324cSopenharmony_ci    // encoder.NumIterations = 3;
1930370b324cSopenharmony_ci    encoder.Salt = g_CrcTable[i & 0xFF];
1931370b324cSopenharmony_ci    encoder.Salt ^= (g_CrcTable[(i >> 8) & 0xFF] << 3);
1932370b324cSopenharmony_ci    // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread
1933370b324cSopenharmony_ci    // printf(" %8x", encoder.Salt);
1934370b324cSopenharmony_ci
1935370b324cSopenharmony_ci    encoder.KeySize = benchProps->KeySize;
1936370b324cSopenharmony_ci
1937370b324cSopenharmony_ci    for (int j = 0; j < 2; j++)
1938370b324cSopenharmony_ci    {
1939370b324cSopenharmony_ci      CBenchProgressInfo *spec = new CBenchProgressInfo;
1940370b324cSopenharmony_ci      encoder.progressInfoSpec[j] = spec;
1941370b324cSopenharmony_ci      encoder.progressInfo[j] = spec;
1942370b324cSopenharmony_ci      spec->Status = &status;
1943370b324cSopenharmony_ci    }
1944370b324cSopenharmony_ci
1945370b324cSopenharmony_ci    if (i == 0)
1946370b324cSopenharmony_ci    {
1947370b324cSopenharmony_ci      CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
1948370b324cSopenharmony_ci      bpi->Callback = callback;
1949370b324cSopenharmony_ci      bpi->BenchInfo.NumIterations = numEncoderThreads;
1950370b324cSopenharmony_ci    }
1951370b324cSopenharmony_ci
1952370b324cSopenharmony_ci    #ifndef Z7_ST
1953370b324cSopenharmony_ci    if (mtEncMode)
1954370b324cSopenharmony_ci    {
1955370b324cSopenharmony_ci      #ifdef USE_ALLOCA
1956370b324cSopenharmony_ci      encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
1957370b324cSopenharmony_ci      #endif
1958370b324cSopenharmony_ci
1959370b324cSopenharmony_ci      encoder.Common = &encoderFlusher.Common;
1960370b324cSopenharmony_ci      encoder.IsGlobalMtMode = numEncoderThreads > 1;
1961370b324cSopenharmony_ci      RINOK(encoder.CreateEncoderThread())
1962370b324cSopenharmony_ci    }
1963370b324cSopenharmony_ci    #endif
1964370b324cSopenharmony_ci  }
1965370b324cSopenharmony_ci
1966370b324cSopenharmony_ci  if (printCallback)
1967370b324cSopenharmony_ci  {
1968370b324cSopenharmony_ci    RINOK(printCallback->CheckBreak())
1969370b324cSopenharmony_ci  }
1970370b324cSopenharmony_ci
1971370b324cSopenharmony_ci  #ifndef Z7_ST
1972370b324cSopenharmony_ci  if (mtEncMode)
1973370b324cSopenharmony_ci  {
1974370b324cSopenharmony_ci    for (i = 0; i < numEncoderThreads; i++)
1975370b324cSopenharmony_ci    {
1976370b324cSopenharmony_ci      CEncoderInfo &encoder = encoders[i];
1977370b324cSopenharmony_ci      const WRes wres = encoder.ReadyEvent.Lock();
1978370b324cSopenharmony_ci      if (wres != 0)
1979370b324cSopenharmony_ci        return HRESULT_FROM_WIN32(wres);
1980370b324cSopenharmony_ci      RINOK(encoder.Results[0])
1981370b324cSopenharmony_ci    }
1982370b324cSopenharmony_ci
1983370b324cSopenharmony_ci    CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0];
1984370b324cSopenharmony_ci    bpi->SetStartTime();
1985370b324cSopenharmony_ci
1986370b324cSopenharmony_ci    const WRes wres = encoderFlusher.StartAndWait();
1987370b324cSopenharmony_ci    if (status.Res == 0 && wres != 0)
1988370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
1989370b324cSopenharmony_ci  }
1990370b324cSopenharmony_ci  else
1991370b324cSopenharmony_ci  #endif
1992370b324cSopenharmony_ci  {
1993370b324cSopenharmony_ci    RINOK(encoders[0].Encode())
1994370b324cSopenharmony_ci  }
1995370b324cSopenharmony_ci
1996370b324cSopenharmony_ci  RINOK(status.Res)
1997370b324cSopenharmony_ci
1998370b324cSopenharmony_ci  CBenchInfo info;
1999370b324cSopenharmony_ci
2000370b324cSopenharmony_ci  encoders[0].progressInfoSpec[0]->SetFinishTime(info);
2001370b324cSopenharmony_ci  info.UnpackSize = 0;
2002370b324cSopenharmony_ci  info.PackSize = 0;
2003370b324cSopenharmony_ci  info.NumIterations = encoders[0].NumIterations;
2004370b324cSopenharmony_ci
2005370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
2006370b324cSopenharmony_ci  {
2007370b324cSopenharmony_ci    const CEncoderInfo &encoder = encoders[i];
2008370b324cSopenharmony_ci    info.UnpackSize += encoder.kBufferSize;
2009370b324cSopenharmony_ci    info.PackSize += encoder.compressedSize;
2010370b324cSopenharmony_ci    // printf("\n%7d\n", encoder.compressedSize);
2011370b324cSopenharmony_ci  }
2012370b324cSopenharmony_ci
2013370b324cSopenharmony_ci  RINOK(callback->SetEncodeResult(info, true))
2014370b324cSopenharmony_ci
2015370b324cSopenharmony_ci
2016370b324cSopenharmony_ci
2017370b324cSopenharmony_ci
2018370b324cSopenharmony_ci  // ---------- Decode ----------
2019370b324cSopenharmony_ci
2020370b324cSopenharmony_ci  status.Res = S_OK;
2021370b324cSopenharmony_ci  status.EncodeMode = false;
2022370b324cSopenharmony_ci
2023370b324cSopenharmony_ci  const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
2024370b324cSopenharmony_ci  #ifndef Z7_ST
2025370b324cSopenharmony_ci  const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity();
2026370b324cSopenharmony_ci  #endif
2027370b324cSopenharmony_ci
2028370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
2029370b324cSopenharmony_ci  {
2030370b324cSopenharmony_ci    CEncoderInfo &encoder = encoders[i];
2031370b324cSopenharmony_ci
2032370b324cSopenharmony_ci    /*
2033370b324cSopenharmony_ci    #ifndef Z7_ST
2034370b324cSopenharmony_ci    // encoder.affinityMode = *affinityMode;
2035370b324cSopenharmony_ci    if (encoder.NumEncoderInternalThreads != 1)
2036370b324cSopenharmony_ci      encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads;
2037370b324cSopenharmony_ci    #endif
2038370b324cSopenharmony_ci    */
2039370b324cSopenharmony_ci
2040370b324cSopenharmony_ci
2041370b324cSopenharmony_ci    if (i == 0)
2042370b324cSopenharmony_ci    {
2043370b324cSopenharmony_ci      encoder.NumIterations = GetNumIterations(
2044370b324cSopenharmony_ci          benchProps->GetNumCommands_Dec(
2045370b324cSopenharmony_ci              encoder.compressedSize,
2046370b324cSopenharmony_ci              encoder.kBufferSize),
2047370b324cSopenharmony_ci          complexInCommands);
2048370b324cSopenharmony_ci      CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
2049370b324cSopenharmony_ci      bpi->Callback = callback;
2050370b324cSopenharmony_ci      bpi->BenchInfo.NumIterations = numDecoderThreads;
2051370b324cSopenharmony_ci      bpi->SetStartTime();
2052370b324cSopenharmony_ci    }
2053370b324cSopenharmony_ci    else
2054370b324cSopenharmony_ci      encoder.NumIterations = encoders[0].NumIterations;
2055370b324cSopenharmony_ci
2056370b324cSopenharmony_ci    #ifndef Z7_ST
2057370b324cSopenharmony_ci    {
2058370b324cSopenharmony_ci      int numSubThreads = method.Get_NumThreads();
2059370b324cSopenharmony_ci      encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads;
2060370b324cSopenharmony_ci    }
2061370b324cSopenharmony_ci    if (mtDecoderMode)
2062370b324cSopenharmony_ci    {
2063370b324cSopenharmony_ci      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2064370b324cSopenharmony_ci      {
2065370b324cSopenharmony_ci        const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
2066370b324cSopenharmony_ci            #ifdef USE_ALLOCA
2067370b324cSopenharmony_ci            , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF
2068370b324cSopenharmony_ci            #endif
2069370b324cSopenharmony_ci            );
2070370b324cSopenharmony_ci        RINOK(res)
2071370b324cSopenharmony_ci      }
2072370b324cSopenharmony_ci    }
2073370b324cSopenharmony_ci    else
2074370b324cSopenharmony_ci    #endif
2075370b324cSopenharmony_ci    {
2076370b324cSopenharmony_ci      RINOK(encoder.Decode(0))
2077370b324cSopenharmony_ci    }
2078370b324cSopenharmony_ci  }
2079370b324cSopenharmony_ci
2080370b324cSopenharmony_ci  #ifndef Z7_ST
2081370b324cSopenharmony_ci  if (mtDecoderMode)
2082370b324cSopenharmony_ci  {
2083370b324cSopenharmony_ci    WRes wres = 0;
2084370b324cSopenharmony_ci    HRESULT res = S_OK;
2085370b324cSopenharmony_ci    for (i = 0; i < numEncoderThreads; i++)
2086370b324cSopenharmony_ci      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2087370b324cSopenharmony_ci      {
2088370b324cSopenharmony_ci        CEncoderInfo &encoder = encoders[i];
2089370b324cSopenharmony_ci        const WRes wres2 = encoder.thread[j].
2090370b324cSopenharmony_ci            // Wait(); // later we can get thread times from thread in UNDER_CE
2091370b324cSopenharmony_ci            Wait_Close();
2092370b324cSopenharmony_ci        if (wres == 0 && wres2 != 0)
2093370b324cSopenharmony_ci          wres = wres2;
2094370b324cSopenharmony_ci        const HRESULT res2 = encoder.Results[j];
2095370b324cSopenharmony_ci        if (res == 0 && res2 != 0)
2096370b324cSopenharmony_ci          res = res2;
2097370b324cSopenharmony_ci      }
2098370b324cSopenharmony_ci    if (wres != 0)
2099370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
2100370b324cSopenharmony_ci    RINOK(res)
2101370b324cSopenharmony_ci  }
2102370b324cSopenharmony_ci  #endif // Z7_ST
2103370b324cSopenharmony_ci
2104370b324cSopenharmony_ci  RINOK(status.Res)
2105370b324cSopenharmony_ci  encoders[0].progressInfoSpec[0]->SetFinishTime(info);
2106370b324cSopenharmony_ci
2107370b324cSopenharmony_ci  /*
2108370b324cSopenharmony_ci  #ifndef Z7_ST
2109370b324cSopenharmony_ci  #ifdef UNDER_CE
2110370b324cSopenharmony_ci  if (mtDecoderMode)
2111370b324cSopenharmony_ci    for (i = 0; i < numEncoderThreads; i++)
2112370b324cSopenharmony_ci      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2113370b324cSopenharmony_ci      {
2114370b324cSopenharmony_ci        FILETIME creationTime, exitTime, kernelTime, userTime;
2115370b324cSopenharmony_ci        if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0)
2116370b324cSopenharmony_ci          info.UserTime += GetTime64(userTime) + GetTime64(kernelTime);
2117370b324cSopenharmony_ci      }
2118370b324cSopenharmony_ci  #endif
2119370b324cSopenharmony_ci  #endif
2120370b324cSopenharmony_ci  */
2121370b324cSopenharmony_ci
2122370b324cSopenharmony_ci  info.UnpackSize = 0;
2123370b324cSopenharmony_ci  info.PackSize = 0;
2124370b324cSopenharmony_ci  info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
2125370b324cSopenharmony_ci
2126370b324cSopenharmony_ci  for (i = 0; i < numEncoderThreads; i++)
2127370b324cSopenharmony_ci  {
2128370b324cSopenharmony_ci    const CEncoderInfo &encoder = encoders[i];
2129370b324cSopenharmony_ci    info.UnpackSize += encoder.kBufferSize;
2130370b324cSopenharmony_ci    info.PackSize += encoder.compressedSize;
2131370b324cSopenharmony_ci  }
2132370b324cSopenharmony_ci
2133370b324cSopenharmony_ci  // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ??
2134370b324cSopenharmony_ci  RINOK(callback->SetDecodeResult(info, true))
2135370b324cSopenharmony_ci
2136370b324cSopenharmony_ci  return S_OK;
2137370b324cSopenharmony_ci}
2138370b324cSopenharmony_ci
2139370b324cSopenharmony_ci
2140370b324cSopenharmony_ci
2141370b324cSopenharmony_cistatic inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog)
2142370b324cSopenharmony_ci{
2143370b324cSopenharmony_ci  /*
2144370b324cSopenharmony_ci  if (dictSizeLog < 32)
2145370b324cSopenharmony_ci    return (UInt32)1 << dictSizeLog;
2146370b324cSopenharmony_ci  else
2147370b324cSopenharmony_ci    return (UInt32)(Int32)-1;
2148370b324cSopenharmony_ci  */
2149370b324cSopenharmony_ci  return (UInt64)1 << dictSizeLog;
2150370b324cSopenharmony_ci}
2151370b324cSopenharmony_ci
2152370b324cSopenharmony_ci
2153370b324cSopenharmony_ci// it's limit of current LZMA implementation that can be changed later
2154370b324cSopenharmony_ci#define kLzmaMaxDictSize ((UInt32)15 << 28)
2155370b324cSopenharmony_ci
2156370b324cSopenharmony_cistatic inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict)
2157370b324cSopenharmony_ci{
2158370b324cSopenharmony_ci  if (dict == 0)
2159370b324cSopenharmony_ci    dict = 1;
2160370b324cSopenharmony_ci  if (dict > kLzmaMaxDictSize)
2161370b324cSopenharmony_ci    dict = kLzmaMaxDictSize;
2162370b324cSopenharmony_ci  UInt32 hs = (UInt32)dict - 1;
2163370b324cSopenharmony_ci  hs |= (hs >> 1);
2164370b324cSopenharmony_ci  hs |= (hs >> 2);
2165370b324cSopenharmony_ci  hs |= (hs >> 4);
2166370b324cSopenharmony_ci  hs |= (hs >> 8);
2167370b324cSopenharmony_ci  hs >>= 1;
2168370b324cSopenharmony_ci  hs |= 0xFFFF;
2169370b324cSopenharmony_ci  if (hs > (1 << 24))
2170370b324cSopenharmony_ci    hs >>= 1;
2171370b324cSopenharmony_ci  hs++;
2172370b324cSopenharmony_ci  hs += (1 << 16);
2173370b324cSopenharmony_ci
2174370b324cSopenharmony_ci  const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
2175370b324cSopenharmony_ci  UInt64 blockSize = (UInt64)dict + (1 << 16)
2176370b324cSopenharmony_ci      + (multiThread ? (1 << 20) : 0);
2177370b324cSopenharmony_ci  blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
2178370b324cSopenharmony_ci  if (blockSize >= kBlockSizeMax)
2179370b324cSopenharmony_ci    blockSize = kBlockSizeMax;
2180370b324cSopenharmony_ci
2181370b324cSopenharmony_ci  UInt64 son = (UInt64)dict;
2182370b324cSopenharmony_ci  if (btMode)
2183370b324cSopenharmony_ci    son *= 2;
2184370b324cSopenharmony_ci  const UInt64 v = (hs + son) * 4 + blockSize +
2185370b324cSopenharmony_ci      (1 << 20) + (multiThread ? (6 << 20) : 0);
2186370b324cSopenharmony_ci
2187370b324cSopenharmony_ci  // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20));
2188370b324cSopenharmony_ci  // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20));
2189370b324cSopenharmony_ci  return v;
2190370b324cSopenharmony_ci}
2191370b324cSopenharmony_ci
2192370b324cSopenharmony_ci
2193370b324cSopenharmony_ciUInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench)
2194370b324cSopenharmony_ci{
2195370b324cSopenharmony_ci  const size_t kBufferSize = (size_t)dictionary + kAdditionalSize;
2196370b324cSopenharmony_ci  const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2;
2197370b324cSopenharmony_ci  if (level < 0)
2198370b324cSopenharmony_ci    level = 5;
2199370b324cSopenharmony_ci  const int algo = (level < 5 ? 0 : 1);
2200370b324cSopenharmony_ci  const int btMode = (algo == 0 ? 0 : 1);
2201370b324cSopenharmony_ci
2202370b324cSopenharmony_ci  UInt32 numBigThreads = numThreads;
2203370b324cSopenharmony_ci  bool lzmaMt = (totalBench || (numThreads > 1 && btMode));
2204370b324cSopenharmony_ci  if (btMode)
2205370b324cSopenharmony_ci  {
2206370b324cSopenharmony_ci    if (!totalBench && lzmaMt)
2207370b324cSopenharmony_ci      numBigThreads /= 2;
2208370b324cSopenharmony_ci  }
2209370b324cSopenharmony_ci  return ((UInt64)kBufferSize + kCompressedBufferSize +
2210370b324cSopenharmony_ci    GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads;
2211370b324cSopenharmony_ci}
2212370b324cSopenharmony_ci
2213370b324cSopenharmony_cistatic UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary)
2214370b324cSopenharmony_ci{
2215370b324cSopenharmony_ci  // dictionary += (dictionary >> 9); // for page tables (virtual memory)
2216370b324cSopenharmony_ci  return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20);
2217370b324cSopenharmony_ci}
2218370b324cSopenharmony_ci
2219370b324cSopenharmony_ci
2220370b324cSopenharmony_ci// ---------- CRC and HASH ----------
2221370b324cSopenharmony_ci
2222370b324cSopenharmony_cistruct CCrcInfo_Base
2223370b324cSopenharmony_ci{
2224370b324cSopenharmony_ci  CMidAlignedBuffer Buffer;
2225370b324cSopenharmony_ci  const Byte *Data;
2226370b324cSopenharmony_ci  size_t Size;
2227370b324cSopenharmony_ci  bool CreateLocalBuf;
2228370b324cSopenharmony_ci  UInt32 CheckSum_Res;
2229370b324cSopenharmony_ci
2230370b324cSopenharmony_ci  CCrcInfo_Base(): CreateLocalBuf(true), CheckSum_Res(0) {}
2231370b324cSopenharmony_ci
2232370b324cSopenharmony_ci  HRESULT Generate(const Byte *data, size_t size);
2233370b324cSopenharmony_ci  HRESULT CrcProcess(UInt64 numIterations,
2234370b324cSopenharmony_ci      const UInt32 *checkSum, IHasher *hf,
2235370b324cSopenharmony_ci      IBenchPrintCallback *callback);
2236370b324cSopenharmony_ci};
2237370b324cSopenharmony_ci
2238370b324cSopenharmony_ci
2239370b324cSopenharmony_ciHRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size)
2240370b324cSopenharmony_ci{
2241370b324cSopenharmony_ci  Size = size;
2242370b324cSopenharmony_ci  Data = data;
2243370b324cSopenharmony_ci  if (!data || CreateLocalBuf)
2244370b324cSopenharmony_ci  {
2245370b324cSopenharmony_ci    ALLOC_WITH_HRESULT(&Buffer, size)
2246370b324cSopenharmony_ci    Data = Buffer;
2247370b324cSopenharmony_ci  }
2248370b324cSopenharmony_ci  if (!data)
2249370b324cSopenharmony_ci    RandGen(Buffer, size);
2250370b324cSopenharmony_ci  else if (CreateLocalBuf && size != 0)
2251370b324cSopenharmony_ci    memcpy(Buffer, data, size);
2252370b324cSopenharmony_ci  return S_OK;
2253370b324cSopenharmony_ci}
2254370b324cSopenharmony_ci
2255370b324cSopenharmony_ci
2256370b324cSopenharmony_ciHRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
2257370b324cSopenharmony_ci    const UInt32 *checkSum, IHasher *hf,
2258370b324cSopenharmony_ci    IBenchPrintCallback *callback)
2259370b324cSopenharmony_ci{
2260370b324cSopenharmony_ci  MY_ALIGN(16)
2261370b324cSopenharmony_ci  Byte hash[64];
2262370b324cSopenharmony_ci  memset(hash, 0, sizeof(hash));
2263370b324cSopenharmony_ci
2264370b324cSopenharmony_ci  CheckSum_Res = 0;
2265370b324cSopenharmony_ci
2266370b324cSopenharmony_ci  const UInt32 hashSize = hf->GetDigestSize();
2267370b324cSopenharmony_ci  if (hashSize > sizeof(hash))
2268370b324cSopenharmony_ci    return S_FALSE;
2269370b324cSopenharmony_ci
2270370b324cSopenharmony_ci  const Byte *buf = Data;
2271370b324cSopenharmony_ci  const size_t size = Size;
2272370b324cSopenharmony_ci  UInt32 checkSum_Prev = 0;
2273370b324cSopenharmony_ci
2274370b324cSopenharmony_ci  UInt64 prev = 0;
2275370b324cSopenharmony_ci  UInt64 cur = 0;
2276370b324cSopenharmony_ci
2277370b324cSopenharmony_ci  for (UInt64 i = 0; i < numIterations; i++)
2278370b324cSopenharmony_ci  {
2279370b324cSopenharmony_ci    hf->Init();
2280370b324cSopenharmony_ci    size_t pos = 0;
2281370b324cSopenharmony_ci    do
2282370b324cSopenharmony_ci    {
2283370b324cSopenharmony_ci      const size_t rem = size - pos;
2284370b324cSopenharmony_ci      const UInt32 kStep = ((UInt32)1 << 31);
2285370b324cSopenharmony_ci      const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
2286370b324cSopenharmony_ci      hf->Update(buf + pos, curSize);
2287370b324cSopenharmony_ci      pos += curSize;
2288370b324cSopenharmony_ci    }
2289370b324cSopenharmony_ci    while (pos != size);
2290370b324cSopenharmony_ci
2291370b324cSopenharmony_ci    hf->Final(hash);
2292370b324cSopenharmony_ci    UInt32 sum = 0;
2293370b324cSopenharmony_ci    for (UInt32 j = 0; j < hashSize; j += 4)
2294370b324cSopenharmony_ci    {
2295370b324cSopenharmony_ci      sum = rotlFixed(sum, 11);
2296370b324cSopenharmony_ci      sum += GetUi32(hash + j);
2297370b324cSopenharmony_ci    }
2298370b324cSopenharmony_ci    if (checkSum)
2299370b324cSopenharmony_ci    {
2300370b324cSopenharmony_ci      if (sum != *checkSum)
2301370b324cSopenharmony_ci        return S_FALSE;
2302370b324cSopenharmony_ci    }
2303370b324cSopenharmony_ci    else
2304370b324cSopenharmony_ci    {
2305370b324cSopenharmony_ci      checkSum_Prev = sum;
2306370b324cSopenharmony_ci      checkSum = &checkSum_Prev;
2307370b324cSopenharmony_ci    }
2308370b324cSopenharmony_ci    if (callback)
2309370b324cSopenharmony_ci    {
2310370b324cSopenharmony_ci      cur += size;
2311370b324cSopenharmony_ci      if (cur - prev >= ((UInt32)1 << 30))
2312370b324cSopenharmony_ci      {
2313370b324cSopenharmony_ci        prev = cur;
2314370b324cSopenharmony_ci        RINOK(callback->CheckBreak())
2315370b324cSopenharmony_ci      }
2316370b324cSopenharmony_ci    }
2317370b324cSopenharmony_ci  }
2318370b324cSopenharmony_ci  CheckSum_Res = checkSum_Prev;
2319370b324cSopenharmony_ci  return S_OK;
2320370b324cSopenharmony_ci}
2321370b324cSopenharmony_ci
2322370b324cSopenharmony_ciextern
2323370b324cSopenharmony_ciUInt32 g_BenchCpuFreqTemp; // we need non-static variavble to disable compiler optimization
2324370b324cSopenharmony_ciUInt32 g_BenchCpuFreqTemp = 1;
2325370b324cSopenharmony_ci
2326370b324cSopenharmony_ci#define YY1 sum += val; sum ^= val;
2327370b324cSopenharmony_ci#define YY3 YY1 YY1 YY1 YY1
2328370b324cSopenharmony_ci#define YY5 YY3 YY3 YY3 YY3
2329370b324cSopenharmony_ci#define YY7 YY5 YY5 YY5 YY5
2330370b324cSopenharmony_cistatic const UInt32 kNumFreqCommands = 128;
2331370b324cSopenharmony_ci
2332370b324cSopenharmony_ciEXTERN_C_BEGIN
2333370b324cSopenharmony_ci
2334370b324cSopenharmony_cistatic UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
2335370b324cSopenharmony_ci{
2336370b324cSopenharmony_ci  for (UInt32 i = 0; i < num; i++)
2337370b324cSopenharmony_ci  {
2338370b324cSopenharmony_ci    YY7
2339370b324cSopenharmony_ci  }
2340370b324cSopenharmony_ci  return sum;
2341370b324cSopenharmony_ci}
2342370b324cSopenharmony_ci
2343370b324cSopenharmony_ciEXTERN_C_END
2344370b324cSopenharmony_ci
2345370b324cSopenharmony_ci
2346370b324cSopenharmony_ci#ifndef Z7_ST
2347370b324cSopenharmony_ci
2348370b324cSopenharmony_cistruct CBaseThreadInfo
2349370b324cSopenharmony_ci{
2350370b324cSopenharmony_ci  NWindows::CThread Thread;
2351370b324cSopenharmony_ci  IBenchPrintCallback *Callback;
2352370b324cSopenharmony_ci  HRESULT CallbackRes;
2353370b324cSopenharmony_ci
2354370b324cSopenharmony_ci  WRes Wait_If_Created()
2355370b324cSopenharmony_ci  {
2356370b324cSopenharmony_ci    if (!Thread.IsCreated())
2357370b324cSopenharmony_ci      return 0;
2358370b324cSopenharmony_ci    return Thread.Wait_Close();
2359370b324cSopenharmony_ci  }
2360370b324cSopenharmony_ci};
2361370b324cSopenharmony_ci
2362370b324cSopenharmony_cistruct CFreqInfo: public CBaseThreadInfo
2363370b324cSopenharmony_ci{
2364370b324cSopenharmony_ci  UInt32 ValRes;
2365370b324cSopenharmony_ci  UInt32 Size;
2366370b324cSopenharmony_ci  UInt64 NumIterations;
2367370b324cSopenharmony_ci};
2368370b324cSopenharmony_ci
2369370b324cSopenharmony_cistatic THREAD_FUNC_DECL FreqThreadFunction(void *param)
2370370b324cSopenharmony_ci{
2371370b324cSopenharmony_ci  CFreqInfo *p = (CFreqInfo *)param;
2372370b324cSopenharmony_ci
2373370b324cSopenharmony_ci  UInt32 sum = g_BenchCpuFreqTemp;
2374370b324cSopenharmony_ci  for (UInt64 k = p->NumIterations; k > 0; k--)
2375370b324cSopenharmony_ci  {
2376370b324cSopenharmony_ci    if (p->Callback)
2377370b324cSopenharmony_ci    {
2378370b324cSopenharmony_ci      p->CallbackRes = p->Callback->CheckBreak();
2379370b324cSopenharmony_ci      if (p->CallbackRes != S_OK)
2380370b324cSopenharmony_ci        break;
2381370b324cSopenharmony_ci    }
2382370b324cSopenharmony_ci    sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp);
2383370b324cSopenharmony_ci  }
2384370b324cSopenharmony_ci  p->ValRes = sum;
2385370b324cSopenharmony_ci  return THREAD_FUNC_RET_ZERO;
2386370b324cSopenharmony_ci}
2387370b324cSopenharmony_ci
2388370b324cSopenharmony_cistruct CFreqThreads
2389370b324cSopenharmony_ci{
2390370b324cSopenharmony_ci  CFreqInfo *Items;
2391370b324cSopenharmony_ci  UInt32 NumThreads;
2392370b324cSopenharmony_ci
2393370b324cSopenharmony_ci  CFreqThreads(): Items(NULL), NumThreads(0) {}
2394370b324cSopenharmony_ci
2395370b324cSopenharmony_ci  WRes WaitAll()
2396370b324cSopenharmony_ci  {
2397370b324cSopenharmony_ci    WRes wres = 0;
2398370b324cSopenharmony_ci    for (UInt32 i = 0; i < NumThreads; i++)
2399370b324cSopenharmony_ci    {
2400370b324cSopenharmony_ci      WRes wres2 = Items[i].Wait_If_Created();
2401370b324cSopenharmony_ci      if (wres == 0 && wres2 != 0)
2402370b324cSopenharmony_ci        wres = wres2;
2403370b324cSopenharmony_ci    }
2404370b324cSopenharmony_ci    NumThreads = 0;
2405370b324cSopenharmony_ci    return wres;
2406370b324cSopenharmony_ci  }
2407370b324cSopenharmony_ci
2408370b324cSopenharmony_ci  ~CFreqThreads()
2409370b324cSopenharmony_ci  {
2410370b324cSopenharmony_ci    WaitAll();
2411370b324cSopenharmony_ci    delete []Items;
2412370b324cSopenharmony_ci  }
2413370b324cSopenharmony_ci};
2414370b324cSopenharmony_ci
2415370b324cSopenharmony_ci
2416370b324cSopenharmony_cistatic THREAD_FUNC_DECL CrcThreadFunction(void *param);
2417370b324cSopenharmony_ci
2418370b324cSopenharmony_cistruct CCrcInfo: public CBaseThreadInfo
2419370b324cSopenharmony_ci{
2420370b324cSopenharmony_ci  const Byte *Data;
2421370b324cSopenharmony_ci  size_t Size;
2422370b324cSopenharmony_ci  UInt64 NumIterations;
2423370b324cSopenharmony_ci  bool CheckSumDefined;
2424370b324cSopenharmony_ci  UInt32 CheckSum;
2425370b324cSopenharmony_ci  CMyComPtr<IHasher> Hasher;
2426370b324cSopenharmony_ci  HRESULT Res;
2427370b324cSopenharmony_ci  UInt32 CheckSum_Res;
2428370b324cSopenharmony_ci
2429370b324cSopenharmony_ci  #ifndef Z7_ST
2430370b324cSopenharmony_ci  NSynchronization::CManualResetEvent ReadyEvent;
2431370b324cSopenharmony_ci  UInt32 ThreadIndex;
2432370b324cSopenharmony_ci  CBenchSyncCommon *Common;
2433370b324cSopenharmony_ci  CAffinityMode AffinityMode;
2434370b324cSopenharmony_ci  #endif
2435370b324cSopenharmony_ci
2436370b324cSopenharmony_ci  // we want to call CCrcInfo_Base::Buffer.Free() in main thread.
2437370b324cSopenharmony_ci  // so we uses non-local CCrcInfo_Base.
2438370b324cSopenharmony_ci  CCrcInfo_Base crcib;
2439370b324cSopenharmony_ci
2440370b324cSopenharmony_ci  HRESULT CreateThread()
2441370b324cSopenharmony_ci  {
2442370b324cSopenharmony_ci    WRes res = 0;
2443370b324cSopenharmony_ci    if (!ReadyEvent.IsCreated())
2444370b324cSopenharmony_ci      res = ReadyEvent.Create();
2445370b324cSopenharmony_ci    if (res == 0)
2446370b324cSopenharmony_ci      res = AffinityMode.CreateThread_WithAffinity(Thread, CrcThreadFunction, this,
2447370b324cSopenharmony_ci          ThreadIndex);
2448370b324cSopenharmony_ci    return HRESULT_FROM_WIN32(res);
2449370b324cSopenharmony_ci  }
2450370b324cSopenharmony_ci
2451370b324cSopenharmony_ci  #ifdef USE_ALLOCA
2452370b324cSopenharmony_ci  size_t AllocaSize;
2453370b324cSopenharmony_ci  #endif
2454370b324cSopenharmony_ci
2455370b324cSopenharmony_ci  void Process();
2456370b324cSopenharmony_ci
2457370b324cSopenharmony_ci  CCrcInfo(): Res(E_FAIL) {}
2458370b324cSopenharmony_ci};
2459370b324cSopenharmony_ci
2460370b324cSopenharmony_cistatic const bool k_Crc_CreateLocalBuf_For_File = true; // for total BW test
2461370b324cSopenharmony_ci// static const bool k_Crc_CreateLocalBuf_For_File = false; // for shared memory read test
2462370b324cSopenharmony_ci
2463370b324cSopenharmony_civoid CCrcInfo::Process()
2464370b324cSopenharmony_ci{
2465370b324cSopenharmony_ci  crcib.CreateLocalBuf = k_Crc_CreateLocalBuf_For_File;
2466370b324cSopenharmony_ci  // we can use additional Generate() passes to reduce some time effects for new page allocation
2467370b324cSopenharmony_ci  // for (unsigned y = 0; y < 10; y++)
2468370b324cSopenharmony_ci  Res = crcib.Generate(Data, Size);
2469370b324cSopenharmony_ci
2470370b324cSopenharmony_ci  // if (Common)
2471370b324cSopenharmony_ci  {
2472370b324cSopenharmony_ci    WRes wres = ReadyEvent.Set();
2473370b324cSopenharmony_ci    if (wres != 0)
2474370b324cSopenharmony_ci    {
2475370b324cSopenharmony_ci      if (Res == 0)
2476370b324cSopenharmony_ci        Res = HRESULT_FROM_WIN32(wres);
2477370b324cSopenharmony_ci      return;
2478370b324cSopenharmony_ci    }
2479370b324cSopenharmony_ci    if (Res != 0)
2480370b324cSopenharmony_ci      return;
2481370b324cSopenharmony_ci
2482370b324cSopenharmony_ci    wres = Common->StartEvent.Lock();
2483370b324cSopenharmony_ci
2484370b324cSopenharmony_ci    if (wres != 0)
2485370b324cSopenharmony_ci    {
2486370b324cSopenharmony_ci      Res = HRESULT_FROM_WIN32(wres);
2487370b324cSopenharmony_ci      return;
2488370b324cSopenharmony_ci    }
2489370b324cSopenharmony_ci    if (Common->ExitMode)
2490370b324cSopenharmony_ci      return;
2491370b324cSopenharmony_ci  }
2492370b324cSopenharmony_ci
2493370b324cSopenharmony_ci  Res = crcib.CrcProcess(NumIterations,
2494370b324cSopenharmony_ci      CheckSumDefined ? &CheckSum : NULL, Hasher,
2495370b324cSopenharmony_ci      Callback);
2496370b324cSopenharmony_ci  CheckSum_Res = crcib.CheckSum_Res;
2497370b324cSopenharmony_ci  /*
2498370b324cSopenharmony_ci  We don't want to include the time of slow CCrcInfo_Base::Buffer.Free()
2499370b324cSopenharmony_ci  to time of benchmark. So we don't free Buffer here
2500370b324cSopenharmony_ci  */
2501370b324cSopenharmony_ci  // crcib.Buffer.Free();
2502370b324cSopenharmony_ci}
2503370b324cSopenharmony_ci
2504370b324cSopenharmony_ci
2505370b324cSopenharmony_cistatic THREAD_FUNC_DECL CrcThreadFunction(void *param)
2506370b324cSopenharmony_ci{
2507370b324cSopenharmony_ci  CCrcInfo *p = (CCrcInfo *)param;
2508370b324cSopenharmony_ci
2509370b324cSopenharmony_ci  #ifdef USE_ALLOCA
2510370b324cSopenharmony_ci  alloca(p->AllocaSize);
2511370b324cSopenharmony_ci  #endif
2512370b324cSopenharmony_ci  p->Process();
2513370b324cSopenharmony_ci  return THREAD_FUNC_RET_ZERO;
2514370b324cSopenharmony_ci}
2515370b324cSopenharmony_ci
2516370b324cSopenharmony_ci
2517370b324cSopenharmony_cistruct CCrcThreads
2518370b324cSopenharmony_ci{
2519370b324cSopenharmony_ci  CCrcInfo *Items;
2520370b324cSopenharmony_ci  unsigned NumThreads;
2521370b324cSopenharmony_ci  CBenchSyncCommon Common;
2522370b324cSopenharmony_ci  bool NeedClose;
2523370b324cSopenharmony_ci
2524370b324cSopenharmony_ci  CCrcThreads(): Items(NULL), NumThreads(0), NeedClose(false) {}
2525370b324cSopenharmony_ci
2526370b324cSopenharmony_ci  WRes StartAndWait(bool exitMode = false);
2527370b324cSopenharmony_ci
2528370b324cSopenharmony_ci  ~CCrcThreads()
2529370b324cSopenharmony_ci  {
2530370b324cSopenharmony_ci    StartAndWait(true);
2531370b324cSopenharmony_ci    delete []Items;
2532370b324cSopenharmony_ci  }
2533370b324cSopenharmony_ci};
2534370b324cSopenharmony_ci
2535370b324cSopenharmony_ci
2536370b324cSopenharmony_ciWRes CCrcThreads::StartAndWait(bool exitMode)
2537370b324cSopenharmony_ci{
2538370b324cSopenharmony_ci  if (!NeedClose)
2539370b324cSopenharmony_ci    return 0;
2540370b324cSopenharmony_ci
2541370b324cSopenharmony_ci  Common.ExitMode = exitMode;
2542370b324cSopenharmony_ci  WRes wres = Common.StartEvent.Set();
2543370b324cSopenharmony_ci
2544370b324cSopenharmony_ci  for (unsigned i = 0; i < NumThreads; i++)
2545370b324cSopenharmony_ci  {
2546370b324cSopenharmony_ci    WRes wres2 = Items[i].Wait_If_Created();
2547370b324cSopenharmony_ci    if (wres == 0 && wres2 != 0)
2548370b324cSopenharmony_ci      wres = wres2;
2549370b324cSopenharmony_ci  }
2550370b324cSopenharmony_ci  NumThreads = 0;
2551370b324cSopenharmony_ci  NeedClose = false;
2552370b324cSopenharmony_ci  return wres;
2553370b324cSopenharmony_ci}
2554370b324cSopenharmony_ci
2555370b324cSopenharmony_ci#endif
2556370b324cSopenharmony_ci
2557370b324cSopenharmony_ci
2558370b324cSopenharmony_cistatic UInt32 CrcCalc1(const Byte *buf, size_t size)
2559370b324cSopenharmony_ci{
2560370b324cSopenharmony_ci  UInt32 crc = CRC_INIT_VAL;
2561370b324cSopenharmony_ci  for (size_t i = 0; i < size; i++)
2562370b324cSopenharmony_ci    crc = CRC_UPDATE_BYTE(crc, buf[i]);
2563370b324cSopenharmony_ci  return CRC_GET_DIGEST(crc);
2564370b324cSopenharmony_ci}
2565370b324cSopenharmony_ci
2566370b324cSopenharmony_ci/*
2567370b324cSopenharmony_cistatic UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG)
2568370b324cSopenharmony_ci{
2569370b324cSopenharmony_ci  RandGen(buf, size, RG);
2570370b324cSopenharmony_ci  return CrcCalc1(buf, size);
2571370b324cSopenharmony_ci}
2572370b324cSopenharmony_ci*/
2573370b324cSopenharmony_ci
2574370b324cSopenharmony_cistatic bool CrcInternalTest()
2575370b324cSopenharmony_ci{
2576370b324cSopenharmony_ci  CAlignedBuffer buffer;
2577370b324cSopenharmony_ci  const size_t kBufferSize0 = (1 << 8);
2578370b324cSopenharmony_ci  const size_t kBufferSize1 = (1 << 10);
2579370b324cSopenharmony_ci  const unsigned kCheckSize = (1 << 5);
2580370b324cSopenharmony_ci  buffer.Alloc(kBufferSize0 + kBufferSize1);
2581370b324cSopenharmony_ci  if (!buffer.IsAllocated())
2582370b324cSopenharmony_ci    return false;
2583370b324cSopenharmony_ci  Byte *buf = (Byte *)buffer;
2584370b324cSopenharmony_ci  size_t i;
2585370b324cSopenharmony_ci  for (i = 0; i < kBufferSize0; i++)
2586370b324cSopenharmony_ci    buf[i] = (Byte)i;
2587370b324cSopenharmony_ci  UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
2588370b324cSopenharmony_ci  if (crc1 != 0x29058C73)
2589370b324cSopenharmony_ci    return false;
2590370b324cSopenharmony_ci  RandGen(buf + kBufferSize0, kBufferSize1);
2591370b324cSopenharmony_ci  for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
2592370b324cSopenharmony_ci    for (unsigned j = 0; j < kCheckSize; j++)
2593370b324cSopenharmony_ci      if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
2594370b324cSopenharmony_ci        return false;
2595370b324cSopenharmony_ci  return true;
2596370b324cSopenharmony_ci}
2597370b324cSopenharmony_ci
2598370b324cSopenharmony_cistruct CBenchMethod
2599370b324cSopenharmony_ci{
2600370b324cSopenharmony_ci  unsigned Weight;
2601370b324cSopenharmony_ci  unsigned DictBits;
2602370b324cSopenharmony_ci  Int32 EncComplex;
2603370b324cSopenharmony_ci  Int32 DecComplexCompr;
2604370b324cSopenharmony_ci  Int32 DecComplexUnc;
2605370b324cSopenharmony_ci  const char *Name;
2606370b324cSopenharmony_ci  // unsigned KeySize;
2607370b324cSopenharmony_ci};
2608370b324cSopenharmony_ci
2609370b324cSopenharmony_ci// #define USE_SW_CMPLX
2610370b324cSopenharmony_ci
2611370b324cSopenharmony_ci#ifdef USE_SW_CMPLX
2612370b324cSopenharmony_ci#define CMPLX(x) ((x) * 1000)
2613370b324cSopenharmony_ci#else
2614370b324cSopenharmony_ci#define CMPLX(x) (x)
2615370b324cSopenharmony_ci#endif
2616370b324cSopenharmony_ci
2617370b324cSopenharmony_cistatic const CBenchMethod g_Bench[] =
2618370b324cSopenharmony_ci{
2619370b324cSopenharmony_ci  // { 40, 17,  357,  145,   20, "LZMA:x1" },
2620370b324cSopenharmony_ci  // { 20, 18,  360,  145,   20, "LZMA2:x1:mt2" },
2621370b324cSopenharmony_ci
2622370b324cSopenharmony_ci  { 20, 18,  360,  145,   20, "LZMA:x1" },
2623370b324cSopenharmony_ci  { 20, 22,  600,  145,   20, "LZMA:x3" },
2624370b324cSopenharmony_ci
2625370b324cSopenharmony_ci  { 80, 24, 1220,  145,   20, "LZMA:x5:mt1" },
2626370b324cSopenharmony_ci  { 80, 24, 1220,  145,   20, "LZMA:x5:mt2" },
2627370b324cSopenharmony_ci
2628370b324cSopenharmony_ci  { 10, 16,  124,   40,   14, "Deflate:x1" },
2629370b324cSopenharmony_ci  { 20, 16,  376,   40,   14, "Deflate:x5" },
2630370b324cSopenharmony_ci  { 10, 16, 1082,   40,   14, "Deflate:x7" },
2631370b324cSopenharmony_ci  { 10, 17,  422,   40,   14, "Deflate64:x5" },
2632370b324cSopenharmony_ci
2633370b324cSopenharmony_ci  { 10, 15,  590,   69,   69, "BZip2:x1" },
2634370b324cSopenharmony_ci  { 20, 19,  815,  122,  122, "BZip2:x5" },
2635370b324cSopenharmony_ci  { 10, 19,  815,  122,  122, "BZip2:x5:mt2" },
2636370b324cSopenharmony_ci  { 10, 19, 2530,  122,  122, "BZip2:x7" },
2637370b324cSopenharmony_ci
2638370b324cSopenharmony_ci  // { 10, 18, 1010,    0, 1150, "PPMDZip:x1" },
2639370b324cSopenharmony_ci  { 10, 18, 1010,    0, 1150, "PPMD:x1" },
2640370b324cSopenharmony_ci  // { 10, 22, 1655,    0, 1830, "PPMDZip:x5" },
2641370b324cSopenharmony_ci  { 10, 22, 1655,    0, 1830, "PPMD:x5" },
2642370b324cSopenharmony_ci
2643370b324cSopenharmony_ci  // {  2,  0,  -16,    0,  -16, "Swap2" },
2644370b324cSopenharmony_ci  {  2,  0,  -16,    0,  -16, "Swap4" },
2645370b324cSopenharmony_ci
2646370b324cSopenharmony_ci  // {  2,  0,    3,    0,    4, "Delta:1" },
2647370b324cSopenharmony_ci  // {  2,  0,    3,    0,    4, "Delta:2" },
2648370b324cSopenharmony_ci  // {  2,  0,    3,    0,    4, "Delta:3" },
2649370b324cSopenharmony_ci  {  2,  0,    3,    0,    4, "Delta:4" },
2650370b324cSopenharmony_ci  // {  2,  0,    3,    0,    4, "Delta:8" },
2651370b324cSopenharmony_ci  // {  2,  0,    3,    0,    4, "Delta:32" },
2652370b324cSopenharmony_ci
2653370b324cSopenharmony_ci  {  2,  0,    2,    0,    2, "BCJ" },
2654370b324cSopenharmony_ci  {  2,  0,    1,    0,    1, "ARM64" },
2655370b324cSopenharmony_ci
2656370b324cSopenharmony_ci  // { 10,  0,   18,    0,   18, "AES128CBC:1" },
2657370b324cSopenharmony_ci  // { 10,  0,   21,    0,   21, "AES192CBC:1" },
2658370b324cSopenharmony_ci  { 10,  0,   24,    0,   24, "AES256CBC:1" },
2659370b324cSopenharmony_ci
2660370b324cSopenharmony_ci  // { 10,  0,   18,    0,   18, "AES128CTR:1" },
2661370b324cSopenharmony_ci  // { 10,  0,   21,    0,   21, "AES192CTR:1" },
2662370b324cSopenharmony_ci  // { 10,  0,   24,    0,   24, "AES256CTR:1" },
2663370b324cSopenharmony_ci  // {  2,  0, CMPLX(6), 0, CMPLX(1), "AES128CBC:2" },
2664370b324cSopenharmony_ci  // {  2,  0, CMPLX(7), 0, CMPLX(1), "AES192CBC:2" },
2665370b324cSopenharmony_ci  {  2,  0, CMPLX(8), 0, CMPLX(1), "AES256CBC:2" },
2666370b324cSopenharmony_ci
2667370b324cSopenharmony_ci  // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES128CTR:2" },
2668370b324cSopenharmony_ci  // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" },
2669370b324cSopenharmony_ci  // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" },
2670370b324cSopenharmony_ci
2671370b324cSopenharmony_ci  // {  1,  0, CMPLX(6), 0, CMPLX(1), "AES128CBC:3" },
2672370b324cSopenharmony_ci  // {  1,  0, CMPLX(7), 0, CMPLX(1), "AES192CBC:3" },
2673370b324cSopenharmony_ci  {  1,  0, CMPLX(8), 0, CMPLX(1), "AES256CBC:3" }
2674370b324cSopenharmony_ci
2675370b324cSopenharmony_ci  // {  1,  0, CMPLX(1), 0, CMPLX(1), "AES128CTR:3" },
2676370b324cSopenharmony_ci  // {  1,  0, CMPLX(1), 0, CMPLX(1), "AES192CTR:3" },
2677370b324cSopenharmony_ci  // {  1,  0, CMPLX(1), 0, CMPLX(1), "AES256CTR:3" },
2678370b324cSopenharmony_ci};
2679370b324cSopenharmony_ci
2680370b324cSopenharmony_cistruct CBenchHash
2681370b324cSopenharmony_ci{
2682370b324cSopenharmony_ci  unsigned Weight;
2683370b324cSopenharmony_ci  UInt32 Complex;
2684370b324cSopenharmony_ci  UInt32 CheckSum;
2685370b324cSopenharmony_ci  const char *Name;
2686370b324cSopenharmony_ci};
2687370b324cSopenharmony_ci
2688370b324cSopenharmony_ci// #define ARM_CRC_MUL 100
2689370b324cSopenharmony_ci#define ARM_CRC_MUL 1
2690370b324cSopenharmony_ci
2691370b324cSopenharmony_ci#define k_Hash_Complex_Mult 256
2692370b324cSopenharmony_ci
2693370b324cSopenharmony_cistatic const CBenchHash g_Hash[] =
2694370b324cSopenharmony_ci{
2695370b324cSopenharmony_ci  // {  1,  1820, 0x21e207bb, "CRC32:1" },
2696370b324cSopenharmony_ci  // { 10,   558, 0x21e207bb, "CRC32:4" },
2697370b324cSopenharmony_ci  { 20,   339, 0x21e207bb, "CRC32:8" } ,
2698370b324cSopenharmony_ci  {  2,   128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
2699370b324cSopenharmony_ci  {  2,    64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
2700370b324cSopenharmony_ci  { 10,   512, 0x41b901d1, "CRC64" },
2701370b324cSopenharmony_ci
2702370b324cSopenharmony_ci  { 10, 5100,       0x7913ba03, "SHA256:1" },
2703370b324cSopenharmony_ci  {  2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
2704370b324cSopenharmony_ci
2705370b324cSopenharmony_ci  { 10, 2340,       0xff769021, "SHA1:1" },
2706370b324cSopenharmony_ci  {  2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
2707370b324cSopenharmony_ci
2708370b324cSopenharmony_ci  {  2,  5500, 0x85189d02, "BLAKE2sp" }
2709370b324cSopenharmony_ci};
2710370b324cSopenharmony_ci
2711370b324cSopenharmony_cistatic void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size)
2712370b324cSopenharmony_ci{
2713370b324cSopenharmony_ci  char s[128];
2714370b324cSopenharmony_ci  unsigned startPos = (unsigned)sizeof(s) - 32;
2715370b324cSopenharmony_ci  memset(s, ' ', startPos);
2716370b324cSopenharmony_ci  ConvertUInt64ToString(value, s + startPos);
2717370b324cSopenharmony_ci  // if (withSpace)
2718370b324cSopenharmony_ci  {
2719370b324cSopenharmony_ci    startPos--;
2720370b324cSopenharmony_ci    size++;
2721370b324cSopenharmony_ci  }
2722370b324cSopenharmony_ci  unsigned len = (unsigned)strlen(s + startPos);
2723370b324cSopenharmony_ci  if (size > len)
2724370b324cSopenharmony_ci  {
2725370b324cSopenharmony_ci    size -= len;
2726370b324cSopenharmony_ci    if (startPos < size)
2727370b324cSopenharmony_ci      startPos = 0;
2728370b324cSopenharmony_ci    else
2729370b324cSopenharmony_ci      startPos -= size;
2730370b324cSopenharmony_ci  }
2731370b324cSopenharmony_ci  f.Print(s + startPos);
2732370b324cSopenharmony_ci}
2733370b324cSopenharmony_ci
2734370b324cSopenharmony_cistatic const unsigned kFieldSize_Name = 12;
2735370b324cSopenharmony_cistatic const unsigned kFieldSize_SmallName = 4;
2736370b324cSopenharmony_cistatic const unsigned kFieldSize_Speed = 9;
2737370b324cSopenharmony_cistatic const unsigned kFieldSize_Usage = 5;
2738370b324cSopenharmony_cistatic const unsigned kFieldSize_RU = 6;
2739370b324cSopenharmony_cistatic const unsigned kFieldSize_Rating = 6;
2740370b324cSopenharmony_cistatic const unsigned kFieldSize_EU = 5;
2741370b324cSopenharmony_cistatic const unsigned kFieldSize_Effec = 5;
2742370b324cSopenharmony_cistatic const unsigned kFieldSize_CrcSpeed = 8;
2743370b324cSopenharmony_ci
2744370b324cSopenharmony_ci
2745370b324cSopenharmony_cistatic const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating;
2746370b324cSopenharmony_cistatic const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec;
2747370b324cSopenharmony_ci
2748370b324cSopenharmony_ci
2749370b324cSopenharmony_cistatic void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size)
2750370b324cSopenharmony_ci{
2751370b324cSopenharmony_ci  PrintNumber(f, (rating + 500000) / 1000000, size);
2752370b324cSopenharmony_ci}
2753370b324cSopenharmony_ci
2754370b324cSopenharmony_ci
2755370b324cSopenharmony_cistatic void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size)
2756370b324cSopenharmony_ci{
2757370b324cSopenharmony_ci  UInt64 v = 0;
2758370b324cSopenharmony_ci  if (divider != 0)
2759370b324cSopenharmony_ci    v = (val * 100 + divider / 2) / divider;
2760370b324cSopenharmony_ci  PrintNumber(f, v, size);
2761370b324cSopenharmony_ci}
2762370b324cSopenharmony_ci
2763370b324cSopenharmony_cistatic void PrintChars(IBenchPrintCallback &f, char c, unsigned size)
2764370b324cSopenharmony_ci{
2765370b324cSopenharmony_ci  char s[256];
2766370b324cSopenharmony_ci  memset(s, (Byte)c, size);
2767370b324cSopenharmony_ci  s[size] = 0;
2768370b324cSopenharmony_ci  f.Print(s);
2769370b324cSopenharmony_ci}
2770370b324cSopenharmony_ci
2771370b324cSopenharmony_cistatic void PrintSpaces(IBenchPrintCallback &f, unsigned size)
2772370b324cSopenharmony_ci{
2773370b324cSopenharmony_ci  PrintChars(f, ' ', size);
2774370b324cSopenharmony_ci}
2775370b324cSopenharmony_ci
2776370b324cSopenharmony_cistatic void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size)
2777370b324cSopenharmony_ci{
2778370b324cSopenharmony_ci  PrintNumber(f, Benchmark_GetUsage_Percents(usage), size);
2779370b324cSopenharmony_ci}
2780370b324cSopenharmony_ci
2781370b324cSopenharmony_cistatic void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq)
2782370b324cSopenharmony_ci{
2783370b324cSopenharmony_ci  PrintUsage(f, usage, kFieldSize_Usage);
2784370b324cSopenharmony_ci  PrintRating(f, rpu, kFieldSize_RU);
2785370b324cSopenharmony_ci  PrintRating(f, rating, kFieldSize_Rating);
2786370b324cSopenharmony_ci  if (showFreq)
2787370b324cSopenharmony_ci  {
2788370b324cSopenharmony_ci    if (cpuFreq == 0)
2789370b324cSopenharmony_ci      PrintSpaces(f, kFieldSize_EUAndEffec);
2790370b324cSopenharmony_ci    else
2791370b324cSopenharmony_ci    {
2792370b324cSopenharmony_ci      PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU);
2793370b324cSopenharmony_ci      PrintPercents(f, rating, cpuFreq, kFieldSize_Effec);
2794370b324cSopenharmony_ci    }
2795370b324cSopenharmony_ci  }
2796370b324cSopenharmony_ci}
2797370b324cSopenharmony_ci
2798370b324cSopenharmony_ci
2799370b324cSopenharmony_civoid CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info)
2800370b324cSopenharmony_ci{
2801370b324cSopenharmony_ci  Speed = info.GetUnpackSizeSpeed();
2802370b324cSopenharmony_ci  Usage = info.GetUsage();
2803370b324cSopenharmony_ci  RPU = info.GetRatingPerUsage(Rating);
2804370b324cSopenharmony_ci}
2805370b324cSopenharmony_ci
2806370b324cSopenharmony_civoid CTotalBenchRes::Mult_For_Weight(unsigned weight)
2807370b324cSopenharmony_ci{
2808370b324cSopenharmony_ci  NumIterations2 *= weight;
2809370b324cSopenharmony_ci  RPU *= weight;
2810370b324cSopenharmony_ci  Rating *= weight;
2811370b324cSopenharmony_ci  Usage *= weight;
2812370b324cSopenharmony_ci  Speed *= weight;
2813370b324cSopenharmony_ci}
2814370b324cSopenharmony_ci
2815370b324cSopenharmony_civoid CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r)
2816370b324cSopenharmony_ci{
2817370b324cSopenharmony_ci  Rating += r.Rating;
2818370b324cSopenharmony_ci  Usage += r.Usage;
2819370b324cSopenharmony_ci  RPU += r.RPU;
2820370b324cSopenharmony_ci  Speed += r.Speed;
2821370b324cSopenharmony_ci    // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
2822370b324cSopenharmony_ci  NumIterations2 += r.NumIterations2;
2823370b324cSopenharmony_ci}
2824370b324cSopenharmony_ci
2825370b324cSopenharmony_cistatic void PrintResults(IBenchPrintCallback *f,
2826370b324cSopenharmony_ci    const CBenchInfo &info,
2827370b324cSopenharmony_ci    unsigned weight,
2828370b324cSopenharmony_ci    UInt64 rating,
2829370b324cSopenharmony_ci    bool showFreq, UInt64 cpuFreq,
2830370b324cSopenharmony_ci    CTotalBenchRes *res)
2831370b324cSopenharmony_ci{
2832370b324cSopenharmony_ci  CTotalBenchRes t;
2833370b324cSopenharmony_ci  t.Rating = rating;
2834370b324cSopenharmony_ci  t.NumIterations2 = 1;
2835370b324cSopenharmony_ci  t.Generate_From_BenchInfo(info);
2836370b324cSopenharmony_ci
2837370b324cSopenharmony_ci  if (f)
2838370b324cSopenharmony_ci  {
2839370b324cSopenharmony_ci    if (t.Speed != 0)
2840370b324cSopenharmony_ci      PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed);
2841370b324cSopenharmony_ci    else
2842370b324cSopenharmony_ci      PrintSpaces(*f, 1 + kFieldSize_Speed);
2843370b324cSopenharmony_ci  }
2844370b324cSopenharmony_ci  if (f)
2845370b324cSopenharmony_ci  {
2846370b324cSopenharmony_ci    PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq);
2847370b324cSopenharmony_ci  }
2848370b324cSopenharmony_ci
2849370b324cSopenharmony_ci  if (res)
2850370b324cSopenharmony_ci  {
2851370b324cSopenharmony_ci    // res->NumIterations1++;
2852370b324cSopenharmony_ci    t.Mult_For_Weight(weight);
2853370b324cSopenharmony_ci    res->Update_With_Res(t);
2854370b324cSopenharmony_ci  }
2855370b324cSopenharmony_ci}
2856370b324cSopenharmony_ci
2857370b324cSopenharmony_cistatic void PrintTotals(IBenchPrintCallback &f,
2858370b324cSopenharmony_ci    bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res)
2859370b324cSopenharmony_ci{
2860370b324cSopenharmony_ci  const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1;
2861370b324cSopenharmony_ci  const UInt64 speed = res.Speed / numIterations2;
2862370b324cSopenharmony_ci  if (showSpeed && speed != 0)
2863370b324cSopenharmony_ci    PrintNumber(f, speed / 1024, kFieldSize_Speed);
2864370b324cSopenharmony_ci  else
2865370b324cSopenharmony_ci    PrintSpaces(f, 1 + kFieldSize_Speed);
2866370b324cSopenharmony_ci
2867370b324cSopenharmony_ci  // PrintSpaces(f, 1 + kFieldSize_Speed);
2868370b324cSopenharmony_ci  // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1;
2869370b324cSopenharmony_ci  PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
2870370b324cSopenharmony_ci}
2871370b324cSopenharmony_ci
2872370b324cSopenharmony_ci
2873370b324cSopenharmony_cistatic void PrintHex(AString &s, UInt64 v)
2874370b324cSopenharmony_ci{
2875370b324cSopenharmony_ci  char temp[32];
2876370b324cSopenharmony_ci  ConvertUInt64ToHex(v, temp);
2877370b324cSopenharmony_ci  s += temp;
2878370b324cSopenharmony_ci}
2879370b324cSopenharmony_ci
2880370b324cSopenharmony_ciAString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
2881370b324cSopenharmony_ci{
2882370b324cSopenharmony_ci  AString s;
2883370b324cSopenharmony_ci  // s.Add_UInt32(ti.numProcessThreads);
2884370b324cSopenharmony_ci  unsigned numSysThreads = ti.GetNumSystemThreads();
2885370b324cSopenharmony_ci  if (ti.GetNumProcessThreads() != numSysThreads)
2886370b324cSopenharmony_ci  {
2887370b324cSopenharmony_ci    // if (ti.numProcessThreads != ti.numSysThreads)
2888370b324cSopenharmony_ci    {
2889370b324cSopenharmony_ci      s += " / ";
2890370b324cSopenharmony_ci      s.Add_UInt32(numSysThreads);
2891370b324cSopenharmony_ci    }
2892370b324cSopenharmony_ci    s += " : ";
2893370b324cSopenharmony_ci    #ifdef _WIN32
2894370b324cSopenharmony_ci    PrintHex(s, ti.processAffinityMask);
2895370b324cSopenharmony_ci    s += " / ";
2896370b324cSopenharmony_ci    PrintHex(s, ti.systemAffinityMask);
2897370b324cSopenharmony_ci    #else
2898370b324cSopenharmony_ci    unsigned i = (numSysThreads + 3) & ~(unsigned)3;
2899370b324cSopenharmony_ci    if (i == 0)
2900370b324cSopenharmony_ci      i = 4;
2901370b324cSopenharmony_ci    for (; i >= 4; )
2902370b324cSopenharmony_ci    {
2903370b324cSopenharmony_ci      i -= 4;
2904370b324cSopenharmony_ci      unsigned val = 0;
2905370b324cSopenharmony_ci      for (unsigned k = 0; k < 4; k++)
2906370b324cSopenharmony_ci      {
2907370b324cSopenharmony_ci        const unsigned bit = (ti.IsCpuSet(i + k) ? 1 : 0);
2908370b324cSopenharmony_ci        val += (bit << k);
2909370b324cSopenharmony_ci      }
2910370b324cSopenharmony_ci      PrintHex(s, val);
2911370b324cSopenharmony_ci    }
2912370b324cSopenharmony_ci    #endif
2913370b324cSopenharmony_ci  }
2914370b324cSopenharmony_ci  return s;
2915370b324cSopenharmony_ci}
2916370b324cSopenharmony_ci
2917370b324cSopenharmony_ci
2918370b324cSopenharmony_ci#ifdef Z7_LARGE_PAGES
2919370b324cSopenharmony_ci
2920370b324cSopenharmony_ci#ifdef _WIN32
2921370b324cSopenharmony_ciextern bool g_LargePagesMode;
2922370b324cSopenharmony_ciextern "C"
2923370b324cSopenharmony_ci{
2924370b324cSopenharmony_ci  extern SIZE_T g_LargePageSize;
2925370b324cSopenharmony_ci}
2926370b324cSopenharmony_ci#endif
2927370b324cSopenharmony_ci
2928370b324cSopenharmony_civoid Add_LargePages_String(AString &s)
2929370b324cSopenharmony_ci{
2930370b324cSopenharmony_ci  #ifdef _WIN32
2931370b324cSopenharmony_ci  if (g_LargePagesMode || g_LargePageSize != 0)
2932370b324cSopenharmony_ci  {
2933370b324cSopenharmony_ci    s.Add_OptSpaced("(LP-");
2934370b324cSopenharmony_ci    PrintSize_KMGT_Or_Hex(s, g_LargePageSize);
2935370b324cSopenharmony_ci    #ifdef MY_CPU_X86_OR_AMD64
2936370b324cSopenharmony_ci    if (CPU_IsSupported_PageGB())
2937370b324cSopenharmony_ci      s += "-1G";
2938370b324cSopenharmony_ci    #endif
2939370b324cSopenharmony_ci    if (!g_LargePagesMode)
2940370b324cSopenharmony_ci      s += "-NA";
2941370b324cSopenharmony_ci    s += ")";
2942370b324cSopenharmony_ci  }
2943370b324cSopenharmony_ci  #else
2944370b324cSopenharmony_ci    s += "";
2945370b324cSopenharmony_ci  #endif
2946370b324cSopenharmony_ci}
2947370b324cSopenharmony_ci
2948370b324cSopenharmony_ci#endif
2949370b324cSopenharmony_ci
2950370b324cSopenharmony_ci
2951370b324cSopenharmony_ci
2952370b324cSopenharmony_cistatic void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
2953370b324cSopenharmony_ci    bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
2954370b324cSopenharmony_ci{
2955370b324cSopenharmony_ci  f.Print("RAM ");
2956370b324cSopenharmony_ci  f.Print(sizeString);
2957370b324cSopenharmony_ci  if (size_Defined)
2958370b324cSopenharmony_ci    PrintNumber(f, (size >> 20), 6);
2959370b324cSopenharmony_ci  else
2960370b324cSopenharmony_ci    f.Print("      ?");
2961370b324cSopenharmony_ci  f.Print(" MB");
2962370b324cSopenharmony_ci
2963370b324cSopenharmony_ci  #ifdef Z7_LARGE_PAGES
2964370b324cSopenharmony_ci  {
2965370b324cSopenharmony_ci    AString s;
2966370b324cSopenharmony_ci    Add_LargePages_String(s);
2967370b324cSopenharmony_ci    f.Print(s);
2968370b324cSopenharmony_ci  }
2969370b324cSopenharmony_ci  #endif
2970370b324cSopenharmony_ci
2971370b324cSopenharmony_ci  f.Print(",  # ");
2972370b324cSopenharmony_ci  f.Print(threadsString);
2973370b324cSopenharmony_ci  PrintNumber(f, numThreads, 3);
2974370b324cSopenharmony_ci}
2975370b324cSopenharmony_ci
2976370b324cSopenharmony_ci
2977370b324cSopenharmony_ci
2978370b324cSopenharmony_cistruct CBenchCallbackToPrint Z7_final: public IBenchCallback
2979370b324cSopenharmony_ci{
2980370b324cSopenharmony_ci  bool NeedPrint;
2981370b324cSopenharmony_ci  bool Use2Columns;
2982370b324cSopenharmony_ci  bool ShowFreq;
2983370b324cSopenharmony_ci  unsigned NameFieldSize;
2984370b324cSopenharmony_ci
2985370b324cSopenharmony_ci  unsigned EncodeWeight;
2986370b324cSopenharmony_ci  unsigned DecodeWeight;
2987370b324cSopenharmony_ci
2988370b324cSopenharmony_ci  UInt64 CpuFreq;
2989370b324cSopenharmony_ci  UInt64 DictSize;
2990370b324cSopenharmony_ci
2991370b324cSopenharmony_ci  IBenchPrintCallback *_file;
2992370b324cSopenharmony_ci  CBenchProps BenchProps;
2993370b324cSopenharmony_ci  CTotalBenchRes EncodeRes;
2994370b324cSopenharmony_ci  CTotalBenchRes DecodeRes;
2995370b324cSopenharmony_ci
2996370b324cSopenharmony_ci  CBenchInfo BenchInfo_Results[2];
2997370b324cSopenharmony_ci
2998370b324cSopenharmony_ci  CBenchCallbackToPrint():
2999370b324cSopenharmony_ci      NeedPrint(true),
3000370b324cSopenharmony_ci      Use2Columns(false),
3001370b324cSopenharmony_ci      ShowFreq(false),
3002370b324cSopenharmony_ci      NameFieldSize(0),
3003370b324cSopenharmony_ci      EncodeWeight(1),
3004370b324cSopenharmony_ci      DecodeWeight(1),
3005370b324cSopenharmony_ci      CpuFreq(0)
3006370b324cSopenharmony_ci      {}
3007370b324cSopenharmony_ci
3008370b324cSopenharmony_ci  void Init() { EncodeRes.Init(); DecodeRes.Init(); }
3009370b324cSopenharmony_ci  void Print(const char *s);
3010370b324cSopenharmony_ci  void NewLine();
3011370b324cSopenharmony_ci
3012370b324cSopenharmony_ci  HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
3013370b324cSopenharmony_ci  HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override;
3014370b324cSopenharmony_ci  HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override;
3015370b324cSopenharmony_ci};
3016370b324cSopenharmony_ci
3017370b324cSopenharmony_ciHRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
3018370b324cSopenharmony_ci{
3019370b324cSopenharmony_ci  ShowFreq = showFreq;
3020370b324cSopenharmony_ci  CpuFreq = cpuFreq;
3021370b324cSopenharmony_ci  return S_OK;
3022370b324cSopenharmony_ci}
3023370b324cSopenharmony_ci
3024370b324cSopenharmony_ciHRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
3025370b324cSopenharmony_ci{
3026370b324cSopenharmony_ci  RINOK(_file->CheckBreak())
3027370b324cSopenharmony_ci  if (final)
3028370b324cSopenharmony_ci    BenchInfo_Results[0] = info;
3029370b324cSopenharmony_ci  if (final)
3030370b324cSopenharmony_ci  if (NeedPrint)
3031370b324cSopenharmony_ci  {
3032370b324cSopenharmony_ci    const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
3033370b324cSopenharmony_ci    PrintResults(_file, info,
3034370b324cSopenharmony_ci        EncodeWeight, rating,
3035370b324cSopenharmony_ci        ShowFreq, CpuFreq, &EncodeRes);
3036370b324cSopenharmony_ci    if (!Use2Columns)
3037370b324cSopenharmony_ci      _file->NewLine();
3038370b324cSopenharmony_ci  }
3039370b324cSopenharmony_ci  return S_OK;
3040370b324cSopenharmony_ci}
3041370b324cSopenharmony_ci
3042370b324cSopenharmony_cistatic const char * const kSep = "  | ";
3043370b324cSopenharmony_ci
3044370b324cSopenharmony_ciHRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
3045370b324cSopenharmony_ci{
3046370b324cSopenharmony_ci  RINOK(_file->CheckBreak())
3047370b324cSopenharmony_ci  if (final)
3048370b324cSopenharmony_ci    BenchInfo_Results[1] = info;
3049370b324cSopenharmony_ci  if (final)
3050370b324cSopenharmony_ci  if (NeedPrint)
3051370b324cSopenharmony_ci  {
3052370b324cSopenharmony_ci    const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
3053370b324cSopenharmony_ci    if (Use2Columns)
3054370b324cSopenharmony_ci      _file->Print(kSep);
3055370b324cSopenharmony_ci    else
3056370b324cSopenharmony_ci      PrintSpaces(*_file, NameFieldSize);
3057370b324cSopenharmony_ci    CBenchInfo info2 = info;
3058370b324cSopenharmony_ci    info2.UnpackSize *= info2.NumIterations;
3059370b324cSopenharmony_ci    info2.PackSize *= info2.NumIterations;
3060370b324cSopenharmony_ci    info2.NumIterations = 1;
3061370b324cSopenharmony_ci    PrintResults(_file, info2,
3062370b324cSopenharmony_ci        DecodeWeight, rating,
3063370b324cSopenharmony_ci        ShowFreq, CpuFreq, &DecodeRes);
3064370b324cSopenharmony_ci  }
3065370b324cSopenharmony_ci  return S_OK;
3066370b324cSopenharmony_ci}
3067370b324cSopenharmony_ci
3068370b324cSopenharmony_civoid CBenchCallbackToPrint::Print(const char *s)
3069370b324cSopenharmony_ci{
3070370b324cSopenharmony_ci  _file->Print(s);
3071370b324cSopenharmony_ci}
3072370b324cSopenharmony_ci
3073370b324cSopenharmony_civoid CBenchCallbackToPrint::NewLine()
3074370b324cSopenharmony_ci{
3075370b324cSopenharmony_ci  _file->NewLine();
3076370b324cSopenharmony_ci}
3077370b324cSopenharmony_ci
3078370b324cSopenharmony_cistatic void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
3079370b324cSopenharmony_ci{
3080370b324cSopenharmony_ci  f.Print(s);
3081370b324cSopenharmony_ci  int numSpaces = (int)size - (int)MyStringLen(s);
3082370b324cSopenharmony_ci  if (numSpaces > 0)
3083370b324cSopenharmony_ci    PrintSpaces(f, (unsigned)numSpaces);
3084370b324cSopenharmony_ci}
3085370b324cSopenharmony_ci
3086370b324cSopenharmony_cistatic void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
3087370b324cSopenharmony_ci{
3088370b324cSopenharmony_ci  int numSpaces = (int)size - (int)MyStringLen(s);
3089370b324cSopenharmony_ci  if (numSpaces > 0)
3090370b324cSopenharmony_ci    PrintSpaces(f, (unsigned)numSpaces);
3091370b324cSopenharmony_ci  f.Print(s);
3092370b324cSopenharmony_ci}
3093370b324cSopenharmony_ci
3094370b324cSopenharmony_ci
3095370b324cSopenharmony_cistatic bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name)
3096370b324cSopenharmony_ci{
3097370b324cSopenharmony_ci  UString wildc = GetUnicodeString(mask);
3098370b324cSopenharmony_ci  UString bname = GetUnicodeString(name);
3099370b324cSopenharmony_ci  wildc.MakeLower_Ascii();
3100370b324cSopenharmony_ci  bname.MakeLower_Ascii();
3101370b324cSopenharmony_ci  return DoesWildcardMatchName(wildc, bname);
3102370b324cSopenharmony_ci}
3103370b324cSopenharmony_ci
3104370b324cSopenharmony_ci
3105370b324cSopenharmony_cistatic HRESULT TotalBench(
3106370b324cSopenharmony_ci    DECL_EXTERNAL_CODECS_LOC_VARS
3107370b324cSopenharmony_ci    const COneMethodInfo &methodMask,
3108370b324cSopenharmony_ci    UInt64 complexInCommands,
3109370b324cSopenharmony_ci  #ifndef Z7_ST
3110370b324cSopenharmony_ci    UInt32 numThreads,
3111370b324cSopenharmony_ci    const CAffinityMode *affinityMode,
3112370b324cSopenharmony_ci  #endif
3113370b324cSopenharmony_ci    bool forceUnpackSize,
3114370b324cSopenharmony_ci    size_t unpackSize,
3115370b324cSopenharmony_ci    const Byte *fileData,
3116370b324cSopenharmony_ci    IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
3117370b324cSopenharmony_ci{
3118370b324cSopenharmony_ci  for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
3119370b324cSopenharmony_ci  {
3120370b324cSopenharmony_ci    const CBenchMethod &bench = g_Bench[i];
3121370b324cSopenharmony_ci    if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
3122370b324cSopenharmony_ci      continue;
3123370b324cSopenharmony_ci    PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
3124370b324cSopenharmony_ci    {
3125370b324cSopenharmony_ci      unsigned keySize = 32;
3126370b324cSopenharmony_ci           if (IsString1PrefixedByString2(bench.Name, "AES128")) keySize = 16;
3127370b324cSopenharmony_ci      else if (IsString1PrefixedByString2(bench.Name, "AES192")) keySize = 24;
3128370b324cSopenharmony_ci      callback->BenchProps.KeySize = keySize;
3129370b324cSopenharmony_ci    }
3130370b324cSopenharmony_ci    callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
3131370b324cSopenharmony_ci    callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
3132370b324cSopenharmony_ci    callback->BenchProps.EncComplex = bench.EncComplex;
3133370b324cSopenharmony_ci
3134370b324cSopenharmony_ci    COneMethodInfo method;
3135370b324cSopenharmony_ci    NCOM::CPropVariant propVariant;
3136370b324cSopenharmony_ci    propVariant = bench.Name;
3137370b324cSopenharmony_ci    RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
3138370b324cSopenharmony_ci
3139370b324cSopenharmony_ci    size_t unpackSize2 = unpackSize;
3140370b324cSopenharmony_ci    if (!forceUnpackSize && bench.DictBits == 0)
3141370b324cSopenharmony_ci      unpackSize2 = kFilterUnpackSize;
3142370b324cSopenharmony_ci
3143370b324cSopenharmony_ci    callback->EncodeWeight = bench.Weight;
3144370b324cSopenharmony_ci    callback->DecodeWeight = bench.Weight;
3145370b324cSopenharmony_ci
3146370b324cSopenharmony_ci    const HRESULT res = MethodBench(
3147370b324cSopenharmony_ci        EXTERNAL_CODECS_LOC_VARS
3148370b324cSopenharmony_ci        complexInCommands,
3149370b324cSopenharmony_ci        #ifndef Z7_ST
3150370b324cSopenharmony_ci        false, numThreads, affinityMode,
3151370b324cSopenharmony_ci        #endif
3152370b324cSopenharmony_ci        method,
3153370b324cSopenharmony_ci        unpackSize2, fileData,
3154370b324cSopenharmony_ci        bench.DictBits,
3155370b324cSopenharmony_ci        printCallback, callback, &callback->BenchProps);
3156370b324cSopenharmony_ci
3157370b324cSopenharmony_ci    if (res == E_NOTIMPL)
3158370b324cSopenharmony_ci    {
3159370b324cSopenharmony_ci      // callback->Print(" ---");
3160370b324cSopenharmony_ci      // we need additional empty line as line for decompression results
3161370b324cSopenharmony_ci      if (!callback->Use2Columns)
3162370b324cSopenharmony_ci        callback->NewLine();
3163370b324cSopenharmony_ci    }
3164370b324cSopenharmony_ci    else
3165370b324cSopenharmony_ci    {
3166370b324cSopenharmony_ci      RINOK(res)
3167370b324cSopenharmony_ci    }
3168370b324cSopenharmony_ci
3169370b324cSopenharmony_ci    callback->NewLine();
3170370b324cSopenharmony_ci  }
3171370b324cSopenharmony_ci  return S_OK;
3172370b324cSopenharmony_ci}
3173370b324cSopenharmony_ci
3174370b324cSopenharmony_ci
3175370b324cSopenharmony_cistruct CFreqBench
3176370b324cSopenharmony_ci{
3177370b324cSopenharmony_ci  // in:
3178370b324cSopenharmony_ci  UInt64 complexInCommands;
3179370b324cSopenharmony_ci  UInt32 numThreads;
3180370b324cSopenharmony_ci  bool showFreq;
3181370b324cSopenharmony_ci  UInt64 specifiedFreq;
3182370b324cSopenharmony_ci
3183370b324cSopenharmony_ci  // out:
3184370b324cSopenharmony_ci  UInt64 CpuFreqRes;
3185370b324cSopenharmony_ci  UInt64 UsageRes;
3186370b324cSopenharmony_ci  UInt32 res;
3187370b324cSopenharmony_ci
3188370b324cSopenharmony_ci  CFreqBench()
3189370b324cSopenharmony_ci    {}
3190370b324cSopenharmony_ci
3191370b324cSopenharmony_ci  HRESULT FreqBench(IBenchPrintCallback *_file
3192370b324cSopenharmony_ci      #ifndef Z7_ST
3193370b324cSopenharmony_ci      , const CAffinityMode *affinityMode
3194370b324cSopenharmony_ci      #endif
3195370b324cSopenharmony_ci      );
3196370b324cSopenharmony_ci};
3197370b324cSopenharmony_ci
3198370b324cSopenharmony_ci
3199370b324cSopenharmony_ciHRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file
3200370b324cSopenharmony_ci    #ifndef Z7_ST
3201370b324cSopenharmony_ci    , const CAffinityMode *affinityMode
3202370b324cSopenharmony_ci    #endif
3203370b324cSopenharmony_ci    )
3204370b324cSopenharmony_ci{
3205370b324cSopenharmony_ci  res = 0;
3206370b324cSopenharmony_ci  CpuFreqRes = 0;
3207370b324cSopenharmony_ci  UsageRes = 0;
3208370b324cSopenharmony_ci
3209370b324cSopenharmony_ci  if (numThreads == 0)
3210370b324cSopenharmony_ci    numThreads = 1;
3211370b324cSopenharmony_ci
3212370b324cSopenharmony_ci  #ifdef Z7_ST
3213370b324cSopenharmony_ci  numThreads = 1;
3214370b324cSopenharmony_ci  #endif
3215370b324cSopenharmony_ci
3216370b324cSopenharmony_ci  const UInt32 complexity = kNumFreqCommands;
3217370b324cSopenharmony_ci  UInt64 numIterations = complexInCommands / complexity;
3218370b324cSopenharmony_ci  UInt32 numIterations2 = 1 << 30;
3219370b324cSopenharmony_ci  if (numIterations > numIterations2)
3220370b324cSopenharmony_ci    numIterations /= numIterations2;
3221370b324cSopenharmony_ci  else
3222370b324cSopenharmony_ci  {
3223370b324cSopenharmony_ci    numIterations2 = (UInt32)numIterations;
3224370b324cSopenharmony_ci    numIterations = 1;
3225370b324cSopenharmony_ci  }
3226370b324cSopenharmony_ci
3227370b324cSopenharmony_ci  CBenchInfoCalc progressInfoSpec;
3228370b324cSopenharmony_ci
3229370b324cSopenharmony_ci  #ifndef Z7_ST
3230370b324cSopenharmony_ci
3231370b324cSopenharmony_ci  bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity();
3232370b324cSopenharmony_ci
3233370b324cSopenharmony_ci  if (mtMode)
3234370b324cSopenharmony_ci  {
3235370b324cSopenharmony_ci    CFreqThreads threads;
3236370b324cSopenharmony_ci    threads.Items = new CFreqInfo[numThreads];
3237370b324cSopenharmony_ci    UInt32 i;
3238370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3239370b324cSopenharmony_ci    {
3240370b324cSopenharmony_ci      CFreqInfo &info = threads.Items[i];
3241370b324cSopenharmony_ci      info.Callback = _file;
3242370b324cSopenharmony_ci      info.CallbackRes = S_OK;
3243370b324cSopenharmony_ci      info.NumIterations = numIterations;
3244370b324cSopenharmony_ci      info.Size = numIterations2;
3245370b324cSopenharmony_ci    }
3246370b324cSopenharmony_ci    progressInfoSpec.SetStartTime();
3247370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3248370b324cSopenharmony_ci    {
3249370b324cSopenharmony_ci      // Sleep(10);
3250370b324cSopenharmony_ci      CFreqInfo &info = threads.Items[i];
3251370b324cSopenharmony_ci      WRes wres = affinityMode->CreateThread_WithAffinity(info.Thread, FreqThreadFunction, &info, i);
3252370b324cSopenharmony_ci      if (info.Thread.IsCreated())
3253370b324cSopenharmony_ci        threads.NumThreads++;
3254370b324cSopenharmony_ci      if (wres != 0)
3255370b324cSopenharmony_ci        return HRESULT_FROM_WIN32(wres);
3256370b324cSopenharmony_ci    }
3257370b324cSopenharmony_ci    WRes wres = threads.WaitAll();
3258370b324cSopenharmony_ci    if (wres != 0)
3259370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
3260370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3261370b324cSopenharmony_ci    {
3262370b324cSopenharmony_ci      RINOK(threads.Items[i].CallbackRes)
3263370b324cSopenharmony_ci    }
3264370b324cSopenharmony_ci  }
3265370b324cSopenharmony_ci  else
3266370b324cSopenharmony_ci  #endif
3267370b324cSopenharmony_ci  {
3268370b324cSopenharmony_ci    progressInfoSpec.SetStartTime();
3269370b324cSopenharmony_ci    UInt32 sum = g_BenchCpuFreqTemp;
3270370b324cSopenharmony_ci    for (UInt64 k = numIterations; k > 0; k--)
3271370b324cSopenharmony_ci    {
3272370b324cSopenharmony_ci      sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp);
3273370b324cSopenharmony_ci      if (_file)
3274370b324cSopenharmony_ci      {
3275370b324cSopenharmony_ci        RINOK(_file->CheckBreak())
3276370b324cSopenharmony_ci      }
3277370b324cSopenharmony_ci    }
3278370b324cSopenharmony_ci    res += sum;
3279370b324cSopenharmony_ci  }
3280370b324cSopenharmony_ci
3281370b324cSopenharmony_ci  if (res == 0x12345678)
3282370b324cSopenharmony_ci  if (_file)
3283370b324cSopenharmony_ci  {
3284370b324cSopenharmony_ci    RINOK(_file->CheckBreak())
3285370b324cSopenharmony_ci  }
3286370b324cSopenharmony_ci
3287370b324cSopenharmony_ci  CBenchInfo info;
3288370b324cSopenharmony_ci  progressInfoSpec.SetFinishTime(info);
3289370b324cSopenharmony_ci
3290370b324cSopenharmony_ci  info.UnpackSize = 0;
3291370b324cSopenharmony_ci  info.PackSize = 0;
3292370b324cSopenharmony_ci  info.NumIterations = 1;
3293370b324cSopenharmony_ci
3294370b324cSopenharmony_ci  const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity;
3295370b324cSopenharmony_ci  const UInt64 rating = info.GetSpeed(numCommands);
3296370b324cSopenharmony_ci  CpuFreqRes = rating / numThreads;
3297370b324cSopenharmony_ci  UsageRes = info.GetUsage();
3298370b324cSopenharmony_ci
3299370b324cSopenharmony_ci  if (_file)
3300370b324cSopenharmony_ci  {
3301370b324cSopenharmony_ci    PrintResults(_file, info,
3302370b324cSopenharmony_ci          0, // weight
3303370b324cSopenharmony_ci          rating,
3304370b324cSopenharmony_ci          showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL);
3305370b324cSopenharmony_ci    RINOK(_file->CheckBreak())
3306370b324cSopenharmony_ci  }
3307370b324cSopenharmony_ci
3308370b324cSopenharmony_ci  return S_OK;
3309370b324cSopenharmony_ci}
3310370b324cSopenharmony_ci
3311370b324cSopenharmony_ci
3312370b324cSopenharmony_ci
3313370b324cSopenharmony_cistatic HRESULT CrcBench(
3314370b324cSopenharmony_ci    DECL_EXTERNAL_CODECS_LOC_VARS
3315370b324cSopenharmony_ci    UInt64 complexInCommands,
3316370b324cSopenharmony_ci    UInt32 numThreads,
3317370b324cSopenharmony_ci    const size_t bufferSize,
3318370b324cSopenharmony_ci    const Byte *fileData,
3319370b324cSopenharmony_ci
3320370b324cSopenharmony_ci    UInt64 &speed,
3321370b324cSopenharmony_ci    UInt64 &usage,
3322370b324cSopenharmony_ci
3323370b324cSopenharmony_ci    UInt32 complexity, unsigned benchWeight,
3324370b324cSopenharmony_ci    const UInt32 *checkSum,
3325370b324cSopenharmony_ci    const COneMethodInfo &method,
3326370b324cSopenharmony_ci    IBenchPrintCallback *_file,
3327370b324cSopenharmony_ci    #ifndef Z7_ST
3328370b324cSopenharmony_ci    const CAffinityMode *affinityMode,
3329370b324cSopenharmony_ci    #endif
3330370b324cSopenharmony_ci    bool showRating,
3331370b324cSopenharmony_ci    CTotalBenchRes *encodeRes,
3332370b324cSopenharmony_ci    bool showFreq, UInt64 cpuFreq)
3333370b324cSopenharmony_ci{
3334370b324cSopenharmony_ci  if (numThreads == 0)
3335370b324cSopenharmony_ci    numThreads = 1;
3336370b324cSopenharmony_ci
3337370b324cSopenharmony_ci  #ifdef Z7_ST
3338370b324cSopenharmony_ci  numThreads = 1;
3339370b324cSopenharmony_ci  #endif
3340370b324cSopenharmony_ci
3341370b324cSopenharmony_ci  const AString &methodName = method.MethodName;
3342370b324cSopenharmony_ci  // methodName.RemoveChar(L'-');
3343370b324cSopenharmony_ci  CMethodId hashID;
3344370b324cSopenharmony_ci  if (!FindHashMethod(
3345370b324cSopenharmony_ci      EXTERNAL_CODECS_LOC_VARS
3346370b324cSopenharmony_ci      methodName, hashID))
3347370b324cSopenharmony_ci    return E_NOTIMPL;
3348370b324cSopenharmony_ci
3349370b324cSopenharmony_ci  /*
3350370b324cSopenharmony_ci  // if will generate random data in each thread, instead of global data
3351370b324cSopenharmony_ci  CMidAlignedBuffer buffer;
3352370b324cSopenharmony_ci  if (!fileData)
3353370b324cSopenharmony_ci  {
3354370b324cSopenharmony_ci    ALLOC_WITH_HRESULT(&buffer, bufferSize)
3355370b324cSopenharmony_ci    RandGen(buffer, bufferSize);
3356370b324cSopenharmony_ci    fileData = buffer;
3357370b324cSopenharmony_ci  }
3358370b324cSopenharmony_ci  */
3359370b324cSopenharmony_ci
3360370b324cSopenharmony_ci  const size_t bsize = (bufferSize == 0 ? 1 : bufferSize);
3361370b324cSopenharmony_ci  UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize;
3362370b324cSopenharmony_ci  if (numIterations == 0)
3363370b324cSopenharmony_ci    numIterations = 1;
3364370b324cSopenharmony_ci
3365370b324cSopenharmony_ci  CBenchInfoCalc progressInfoSpec;
3366370b324cSopenharmony_ci  CBenchInfo info;
3367370b324cSopenharmony_ci
3368370b324cSopenharmony_ci  #ifndef Z7_ST
3369370b324cSopenharmony_ci  bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity();
3370370b324cSopenharmony_ci
3371370b324cSopenharmony_ci  if (mtEncMode)
3372370b324cSopenharmony_ci  {
3373370b324cSopenharmony_ci    CCrcThreads threads;
3374370b324cSopenharmony_ci    threads.Items = new CCrcInfo[numThreads];
3375370b324cSopenharmony_ci    {
3376370b324cSopenharmony_ci      WRes wres = threads.Common.StartEvent.Create();
3377370b324cSopenharmony_ci      if (wres != 0)
3378370b324cSopenharmony_ci        return HRESULT_FROM_WIN32(wres);
3379370b324cSopenharmony_ci      threads.NeedClose = true;
3380370b324cSopenharmony_ci    }
3381370b324cSopenharmony_ci
3382370b324cSopenharmony_ci    UInt32 i;
3383370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3384370b324cSopenharmony_ci    {
3385370b324cSopenharmony_ci      CCrcInfo &ci = threads.Items[i];
3386370b324cSopenharmony_ci      AString name;
3387370b324cSopenharmony_ci      RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher))
3388370b324cSopenharmony_ci      if (!ci.Hasher)
3389370b324cSopenharmony_ci        return E_NOTIMPL;
3390370b324cSopenharmony_ci      CMyComPtr<ICompressSetCoderProperties> scp;
3391370b324cSopenharmony_ci      ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
3392370b324cSopenharmony_ci      if (scp)
3393370b324cSopenharmony_ci      {
3394370b324cSopenharmony_ci        RINOK(method.SetCoderProps(scp))
3395370b324cSopenharmony_ci      }
3396370b324cSopenharmony_ci
3397370b324cSopenharmony_ci      ci.Callback = _file;
3398370b324cSopenharmony_ci      ci.Data = fileData;
3399370b324cSopenharmony_ci      ci.NumIterations = numIterations;
3400370b324cSopenharmony_ci      ci.Size = bufferSize;
3401370b324cSopenharmony_ci      ci.CheckSumDefined = false;
3402370b324cSopenharmony_ci      if (checkSum)
3403370b324cSopenharmony_ci      {
3404370b324cSopenharmony_ci        ci.CheckSum = *checkSum;
3405370b324cSopenharmony_ci        ci.CheckSumDefined = true;
3406370b324cSopenharmony_ci      }
3407370b324cSopenharmony_ci
3408370b324cSopenharmony_ci      #ifdef USE_ALLOCA
3409370b324cSopenharmony_ci      ci.AllocaSize = (i * 16 * 21) & 0x7FF;
3410370b324cSopenharmony_ci      #endif
3411370b324cSopenharmony_ci    }
3412370b324cSopenharmony_ci
3413370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3414370b324cSopenharmony_ci    {
3415370b324cSopenharmony_ci      CCrcInfo &ci = threads.Items[i];
3416370b324cSopenharmony_ci      ci.ThreadIndex = i;
3417370b324cSopenharmony_ci      ci.Common = &threads.Common;
3418370b324cSopenharmony_ci      ci.AffinityMode = *affinityMode;
3419370b324cSopenharmony_ci      HRESULT hres = ci.CreateThread();
3420370b324cSopenharmony_ci      if (ci.Thread.IsCreated())
3421370b324cSopenharmony_ci        threads.NumThreads++;
3422370b324cSopenharmony_ci      if (hres != 0)
3423370b324cSopenharmony_ci        return hres;
3424370b324cSopenharmony_ci    }
3425370b324cSopenharmony_ci
3426370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3427370b324cSopenharmony_ci    {
3428370b324cSopenharmony_ci      CCrcInfo &ci = threads.Items[i];
3429370b324cSopenharmony_ci      WRes wres = ci.ReadyEvent.Lock();
3430370b324cSopenharmony_ci      if (wres != 0)
3431370b324cSopenharmony_ci        return HRESULT_FROM_WIN32(wres);
3432370b324cSopenharmony_ci      RINOK(ci.Res)
3433370b324cSopenharmony_ci    }
3434370b324cSopenharmony_ci
3435370b324cSopenharmony_ci    progressInfoSpec.SetStartTime();
3436370b324cSopenharmony_ci
3437370b324cSopenharmony_ci    WRes wres = threads.StartAndWait();
3438370b324cSopenharmony_ci    if (wres != 0)
3439370b324cSopenharmony_ci      return HRESULT_FROM_WIN32(wres);
3440370b324cSopenharmony_ci
3441370b324cSopenharmony_ci    progressInfoSpec.SetFinishTime(info);
3442370b324cSopenharmony_ci
3443370b324cSopenharmony_ci    for (i = 0; i < numThreads; i++)
3444370b324cSopenharmony_ci    {
3445370b324cSopenharmony_ci      RINOK(threads.Items[i].Res)
3446370b324cSopenharmony_ci      if (i != 0)
3447370b324cSopenharmony_ci        if (threads.Items[i].CheckSum_Res !=
3448370b324cSopenharmony_ci            threads.Items[i - 1].CheckSum_Res)
3449370b324cSopenharmony_ci          return S_FALSE;
3450370b324cSopenharmony_ci    }
3451370b324cSopenharmony_ci  }
3452370b324cSopenharmony_ci  else
3453370b324cSopenharmony_ci  #endif
3454370b324cSopenharmony_ci  {
3455370b324cSopenharmony_ci    CMyComPtr<IHasher> hasher;
3456370b324cSopenharmony_ci    AString name;
3457370b324cSopenharmony_ci    RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher))
3458370b324cSopenharmony_ci    if (!hasher)
3459370b324cSopenharmony_ci      return E_NOTIMPL;
3460370b324cSopenharmony_ci    CMyComPtr<ICompressSetCoderProperties> scp;
3461370b324cSopenharmony_ci    hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
3462370b324cSopenharmony_ci    if (scp)
3463370b324cSopenharmony_ci    {
3464370b324cSopenharmony_ci      RINOK(method.SetCoderProps(scp))
3465370b324cSopenharmony_ci    }
3466370b324cSopenharmony_ci    CCrcInfo_Base crcib;
3467370b324cSopenharmony_ci    crcib.CreateLocalBuf = false;
3468370b324cSopenharmony_ci    RINOK(crcib.Generate(fileData, bufferSize))
3469370b324cSopenharmony_ci    progressInfoSpec.SetStartTime();
3470370b324cSopenharmony_ci    RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file))
3471370b324cSopenharmony_ci    progressInfoSpec.SetFinishTime(info);
3472370b324cSopenharmony_ci  }
3473370b324cSopenharmony_ci
3474370b324cSopenharmony_ci
3475370b324cSopenharmony_ci  UInt64 unpSize = numIterations * bufferSize;
3476370b324cSopenharmony_ci  UInt64 unpSizeThreads = unpSize * numThreads;
3477370b324cSopenharmony_ci  info.UnpackSize = unpSizeThreads;
3478370b324cSopenharmony_ci  info.PackSize = unpSizeThreads;
3479370b324cSopenharmony_ci  info.NumIterations = 1;
3480370b324cSopenharmony_ci
3481370b324cSopenharmony_ci  if (_file)
3482370b324cSopenharmony_ci  {
3483370b324cSopenharmony_ci    if (showRating)
3484370b324cSopenharmony_ci    {
3485370b324cSopenharmony_ci      UInt64 unpSizeThreads2 = unpSizeThreads;
3486370b324cSopenharmony_ci      if (unpSizeThreads2 == 0)
3487370b324cSopenharmony_ci        unpSizeThreads2 = numIterations * 1 * numThreads;
3488370b324cSopenharmony_ci      const UInt64 numCommands = unpSizeThreads2 * complexity / 256;
3489370b324cSopenharmony_ci      const UInt64 rating = info.GetSpeed(numCommands);
3490370b324cSopenharmony_ci      PrintResults(_file, info,
3491370b324cSopenharmony_ci          benchWeight, rating,
3492370b324cSopenharmony_ci          showFreq, cpuFreq, encodeRes);
3493370b324cSopenharmony_ci    }
3494370b324cSopenharmony_ci    RINOK(_file->CheckBreak())
3495370b324cSopenharmony_ci  }
3496370b324cSopenharmony_ci
3497370b324cSopenharmony_ci  speed = info.GetSpeed(unpSizeThreads);
3498370b324cSopenharmony_ci  usage = info.GetUsage();
3499370b324cSopenharmony_ci
3500370b324cSopenharmony_ci  return S_OK;
3501370b324cSopenharmony_ci}
3502370b324cSopenharmony_ci
3503370b324cSopenharmony_ci
3504370b324cSopenharmony_ci
3505370b324cSopenharmony_cistatic HRESULT TotalBench_Hash(
3506370b324cSopenharmony_ci    DECL_EXTERNAL_CODECS_LOC_VARS
3507370b324cSopenharmony_ci    const COneMethodInfo &methodMask,
3508370b324cSopenharmony_ci    UInt64 complexInCommands,
3509370b324cSopenharmony_ci    UInt32 numThreads,
3510370b324cSopenharmony_ci    size_t bufSize,
3511370b324cSopenharmony_ci    const Byte *fileData,
3512370b324cSopenharmony_ci    IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback,
3513370b324cSopenharmony_ci    #ifndef Z7_ST
3514370b324cSopenharmony_ci    const CAffinityMode *affinityMode,
3515370b324cSopenharmony_ci    #endif
3516370b324cSopenharmony_ci    CTotalBenchRes *encodeRes,
3517370b324cSopenharmony_ci    bool showFreq, UInt64 cpuFreq)
3518370b324cSopenharmony_ci{
3519370b324cSopenharmony_ci  for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
3520370b324cSopenharmony_ci  {
3521370b324cSopenharmony_ci    const CBenchHash &bench = g_Hash[i];
3522370b324cSopenharmony_ci    if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
3523370b324cSopenharmony_ci      continue;
3524370b324cSopenharmony_ci    PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
3525370b324cSopenharmony_ci    // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
3526370b324cSopenharmony_ci    // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
3527370b324cSopenharmony_ci    // callback->BenchProps.EncComplex = bench.EncComplex;
3528370b324cSopenharmony_ci
3529370b324cSopenharmony_ci    COneMethodInfo method;
3530370b324cSopenharmony_ci    NCOM::CPropVariant propVariant;
3531370b324cSopenharmony_ci    propVariant = bench.Name;
3532370b324cSopenharmony_ci    RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
3533370b324cSopenharmony_ci
3534370b324cSopenharmony_ci    UInt64 speed, usage;
3535370b324cSopenharmony_ci
3536370b324cSopenharmony_ci    const HRESULT res = CrcBench(
3537370b324cSopenharmony_ci        EXTERNAL_CODECS_LOC_VARS
3538370b324cSopenharmony_ci        complexInCommands,
3539370b324cSopenharmony_ci        numThreads, bufSize, fileData,
3540370b324cSopenharmony_ci        speed, usage,
3541370b324cSopenharmony_ci        bench.Complex, bench.Weight,
3542370b324cSopenharmony_ci        (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL,
3543370b324cSopenharmony_ci        method,
3544370b324cSopenharmony_ci        printCallback,
3545370b324cSopenharmony_ci     #ifndef Z7_ST
3546370b324cSopenharmony_ci        affinityMode,
3547370b324cSopenharmony_ci     #endif
3548370b324cSopenharmony_ci        true, // showRating
3549370b324cSopenharmony_ci        encodeRes, showFreq, cpuFreq);
3550370b324cSopenharmony_ci    if (res == E_NOTIMPL)
3551370b324cSopenharmony_ci    {
3552370b324cSopenharmony_ci      // callback->Print(" ---");
3553370b324cSopenharmony_ci    }
3554370b324cSopenharmony_ci    else
3555370b324cSopenharmony_ci    {
3556370b324cSopenharmony_ci      RINOK(res)
3557370b324cSopenharmony_ci    }
3558370b324cSopenharmony_ci    callback->NewLine();
3559370b324cSopenharmony_ci  }
3560370b324cSopenharmony_ci  return S_OK;
3561370b324cSopenharmony_ci}
3562370b324cSopenharmony_ci
3563370b324cSopenharmony_cistruct CTempValues
3564370b324cSopenharmony_ci{
3565370b324cSopenharmony_ci  UInt64 *Values;
3566370b324cSopenharmony_ci  CTempValues(): Values(NULL) {}
3567370b324cSopenharmony_ci  void Alloc(UInt32 num) { Values = new UInt64[num]; }
3568370b324cSopenharmony_ci  ~CTempValues() { delete []Values; }
3569370b324cSopenharmony_ci};
3570370b324cSopenharmony_ci
3571370b324cSopenharmony_cistatic void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
3572370b324cSopenharmony_ci{
3573370b324cSopenharmony_ci  const wchar_t *end;
3574370b324cSopenharmony_ci  UInt64 result = ConvertStringToUInt64(s, &end);
3575370b324cSopenharmony_ci  if (*end != 0 || s.IsEmpty())
3576370b324cSopenharmony_ci    prop = s;
3577370b324cSopenharmony_ci  else if (result <= (UInt32)0xFFFFFFFF)
3578370b324cSopenharmony_ci    prop = (UInt32)result;
3579370b324cSopenharmony_ci  else
3580370b324cSopenharmony_ci    prop = result;
3581370b324cSopenharmony_ci}
3582370b324cSopenharmony_ci
3583370b324cSopenharmony_ci
3584370b324cSopenharmony_cistatic bool AreSameMethodNames(const char *fullName, const char *shortName)
3585370b324cSopenharmony_ci{
3586370b324cSopenharmony_ci  return StringsAreEqualNoCase_Ascii(fullName, shortName);
3587370b324cSopenharmony_ci}
3588370b324cSopenharmony_ci
3589370b324cSopenharmony_ci
3590370b324cSopenharmony_ci
3591370b324cSopenharmony_ci
3592370b324cSopenharmony_cistatic void Print_Usage_and_Threads(IBenchPrintCallback &f, UInt64 usage, UInt32 threads)
3593370b324cSopenharmony_ci{
3594370b324cSopenharmony_ci  PrintRequirements(f, "usage:", true, usage, "Benchmark threads:   ", threads);
3595370b324cSopenharmony_ci}
3596370b324cSopenharmony_ci
3597370b324cSopenharmony_ci
3598370b324cSopenharmony_cistatic void Print_Delimiter(IBenchPrintCallback &f)
3599370b324cSopenharmony_ci{
3600370b324cSopenharmony_ci  f.Print(" |");
3601370b324cSopenharmony_ci}
3602370b324cSopenharmony_ci
3603370b324cSopenharmony_cistatic void Print_Pow(IBenchPrintCallback &f, unsigned pow)
3604370b324cSopenharmony_ci{
3605370b324cSopenharmony_ci  char s[16];
3606370b324cSopenharmony_ci  ConvertUInt32ToString(pow, s);
3607370b324cSopenharmony_ci  unsigned pos = MyStringLen(s);
3608370b324cSopenharmony_ci  s[pos++] = ':';
3609370b324cSopenharmony_ci  s[pos] = 0;
3610370b324cSopenharmony_ci  PrintLeft(f, s, kFieldSize_SmallName); // 4
3611370b324cSopenharmony_ci}
3612370b324cSopenharmony_ci
3613370b324cSopenharmony_cistatic void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f,
3614370b324cSopenharmony_ci    UInt64 usage, UInt64 speed)
3615370b324cSopenharmony_ci{
3616370b324cSopenharmony_ci  PrintUsage(f, usage, kFieldSize_Usage);
3617370b324cSopenharmony_ci  PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed);
3618370b324cSopenharmony_ci}
3619370b324cSopenharmony_ci
3620370b324cSopenharmony_ci
3621370b324cSopenharmony_ciHRESULT Bench(
3622370b324cSopenharmony_ci    DECL_EXTERNAL_CODECS_LOC_VARS
3623370b324cSopenharmony_ci    IBenchPrintCallback *printCallback,
3624370b324cSopenharmony_ci    IBenchCallback *benchCallback,
3625370b324cSopenharmony_ci    const CObjectVector<CProperty> &props,
3626370b324cSopenharmony_ci    UInt32 numIterations,
3627370b324cSopenharmony_ci    bool multiDict,
3628370b324cSopenharmony_ci    IBenchFreqCallback *freqCallback)
3629370b324cSopenharmony_ci{
3630370b324cSopenharmony_ci  if (!CrcInternalTest())
3631370b324cSopenharmony_ci    return E_FAIL;
3632370b324cSopenharmony_ci
3633370b324cSopenharmony_ci  UInt32 numCPUs = 1;
3634370b324cSopenharmony_ci  UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
3635370b324cSopenharmony_ci
3636370b324cSopenharmony_ci  NSystem::CProcessAffinity threadsInfo;
3637370b324cSopenharmony_ci  threadsInfo.InitST();
3638370b324cSopenharmony_ci
3639370b324cSopenharmony_ci  #ifndef Z7_ST
3640370b324cSopenharmony_ci
3641370b324cSopenharmony_ci  if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0)
3642370b324cSopenharmony_ci    numCPUs = threadsInfo.GetNumProcessThreads();
3643370b324cSopenharmony_ci  else
3644370b324cSopenharmony_ci    numCPUs = NSystem::GetNumberOfProcessors();
3645370b324cSopenharmony_ci
3646370b324cSopenharmony_ci  #endif
3647370b324cSopenharmony_ci
3648370b324cSopenharmony_ci  // numCPUs = 24;
3649370b324cSopenharmony_ci  /*
3650370b324cSopenharmony_ci  {
3651370b324cSopenharmony_ci    DWORD_PTR mask = (1 << 0);
3652370b324cSopenharmony_ci    DWORD_PTR old = SetThreadAffinityMask(GetCurrentThread(), mask);
3653370b324cSopenharmony_ci    old = old;
3654370b324cSopenharmony_ci    DWORD_PTR old2 = SetThreadAffinityMask(GetCurrentThread(), mask);
3655370b324cSopenharmony_ci    old2 = old2;
3656370b324cSopenharmony_ci    return 0;
3657370b324cSopenharmony_ci  }
3658370b324cSopenharmony_ci  */
3659370b324cSopenharmony_ci
3660370b324cSopenharmony_ci  bool ramSize_Defined = NSystem::GetRamSize(ramSize);
3661370b324cSopenharmony_ci
3662370b324cSopenharmony_ci  UInt32 numThreadsSpecified = numCPUs;
3663370b324cSopenharmony_ci  bool needSetComplexity = false;
3664370b324cSopenharmony_ci  UInt32 testTimeMs = kComplexInMs;
3665370b324cSopenharmony_ci  UInt32 startDicLog = 22;
3666370b324cSopenharmony_ci  bool startDicLog_Defined = false;
3667370b324cSopenharmony_ci  UInt64 specifiedFreq = 0;
3668370b324cSopenharmony_ci  bool multiThreadTests = false;
3669370b324cSopenharmony_ci  UInt64 complexInCommands = kComplexInCommands;
3670370b324cSopenharmony_ci  UInt32 numThreads_Start = 1;
3671370b324cSopenharmony_ci
3672370b324cSopenharmony_ci  #ifndef Z7_ST
3673370b324cSopenharmony_ci  CAffinityMode affinityMode;
3674370b324cSopenharmony_ci  #endif
3675370b324cSopenharmony_ci
3676370b324cSopenharmony_ci
3677370b324cSopenharmony_ci  COneMethodInfo method;
3678370b324cSopenharmony_ci
3679370b324cSopenharmony_ci  CMidAlignedBuffer fileDataBuffer;
3680370b324cSopenharmony_ci  bool use_fileData = false;
3681370b324cSopenharmony_ci  bool isFixedDict = false;
3682370b324cSopenharmony_ci
3683370b324cSopenharmony_ci  {
3684370b324cSopenharmony_ci  unsigned i;
3685370b324cSopenharmony_ci
3686370b324cSopenharmony_ci  if (printCallback)
3687370b324cSopenharmony_ci  {
3688370b324cSopenharmony_ci    for (i = 0; i < props.Size(); i++)
3689370b324cSopenharmony_ci    {
3690370b324cSopenharmony_ci      const CProperty &property = props[i];
3691370b324cSopenharmony_ci      printCallback->Print(" ");
3692370b324cSopenharmony_ci      printCallback->Print(GetAnsiString(property.Name));
3693370b324cSopenharmony_ci      if (!property.Value.IsEmpty())
3694370b324cSopenharmony_ci      {
3695370b324cSopenharmony_ci        printCallback->Print("=");
3696370b324cSopenharmony_ci        printCallback->Print(GetAnsiString(property.Value));
3697370b324cSopenharmony_ci      }
3698370b324cSopenharmony_ci    }
3699370b324cSopenharmony_ci    if (!props.IsEmpty())
3700370b324cSopenharmony_ci      printCallback->NewLine();
3701370b324cSopenharmony_ci  }
3702370b324cSopenharmony_ci
3703370b324cSopenharmony_ci
3704370b324cSopenharmony_ci  for (i = 0; i < props.Size(); i++)
3705370b324cSopenharmony_ci  {
3706370b324cSopenharmony_ci    const CProperty &property = props[i];
3707370b324cSopenharmony_ci    UString name (property.Name);
3708370b324cSopenharmony_ci    name.MakeLower_Ascii();
3709370b324cSopenharmony_ci
3710370b324cSopenharmony_ci    if (name.IsEqualTo("file"))
3711370b324cSopenharmony_ci    {
3712370b324cSopenharmony_ci      if (property.Value.IsEmpty())
3713370b324cSopenharmony_ci        return E_INVALIDARG;
3714370b324cSopenharmony_ci
3715370b324cSopenharmony_ci      NFile::NIO::CInFile file;
3716370b324cSopenharmony_ci      if (!file.Open(us2fs(property.Value)))
3717370b324cSopenharmony_ci        return GetLastError_noZero_HRESULT();
3718370b324cSopenharmony_ci      size_t len;
3719370b324cSopenharmony_ci      {
3720370b324cSopenharmony_ci        UInt64 len64;
3721370b324cSopenharmony_ci        if (!file.GetLength(len64))
3722370b324cSopenharmony_ci          return GetLastError_noZero_HRESULT();
3723370b324cSopenharmony_ci        if (printCallback)
3724370b324cSopenharmony_ci        {
3725370b324cSopenharmony_ci          printCallback->Print("file size =");
3726370b324cSopenharmony_ci          PrintNumber(*printCallback, len64, 0);
3727370b324cSopenharmony_ci          printCallback->NewLine();
3728370b324cSopenharmony_ci        }
3729370b324cSopenharmony_ci        len = (size_t)len64;
3730370b324cSopenharmony_ci        if (len != len64)
3731370b324cSopenharmony_ci          return E_INVALIDARG;
3732370b324cSopenharmony_ci      }
3733370b324cSopenharmony_ci
3734370b324cSopenharmony_ci      // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here
3735370b324cSopenharmony_ci
3736370b324cSopenharmony_ci      ALLOC_WITH_HRESULT(&fileDataBuffer, len)
3737370b324cSopenharmony_ci      use_fileData = true;
3738370b324cSopenharmony_ci
3739370b324cSopenharmony_ci      {
3740370b324cSopenharmony_ci        size_t processed;
3741370b324cSopenharmony_ci        if (!file.ReadFull((Byte *)fileDataBuffer, len, processed))
3742370b324cSopenharmony_ci          return GetLastError_noZero_HRESULT();
3743370b324cSopenharmony_ci        if (processed != len)
3744370b324cSopenharmony_ci          return E_FAIL;
3745370b324cSopenharmony_ci      }
3746370b324cSopenharmony_ci      continue;
3747370b324cSopenharmony_ci    }
3748370b324cSopenharmony_ci
3749370b324cSopenharmony_ci    NCOM::CPropVariant propVariant;
3750370b324cSopenharmony_ci    if (!property.Value.IsEmpty())
3751370b324cSopenharmony_ci      ParseNumberString(property.Value, propVariant);
3752370b324cSopenharmony_ci
3753370b324cSopenharmony_ci    if (name.IsEqualTo("time"))
3754370b324cSopenharmony_ci    {
3755370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
3756370b324cSopenharmony_ci      needSetComplexity = true;
3757370b324cSopenharmony_ci      testTimeMs *= 1000;
3758370b324cSopenharmony_ci      continue;
3759370b324cSopenharmony_ci    }
3760370b324cSopenharmony_ci
3761370b324cSopenharmony_ci    if (name.IsEqualTo("timems"))
3762370b324cSopenharmony_ci    {
3763370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
3764370b324cSopenharmony_ci      needSetComplexity = true;
3765370b324cSopenharmony_ci      continue;
3766370b324cSopenharmony_ci    }
3767370b324cSopenharmony_ci
3768370b324cSopenharmony_ci    if (name.IsEqualTo("tic"))
3769370b324cSopenharmony_ci    {
3770370b324cSopenharmony_ci      UInt32 v;
3771370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, v))
3772370b324cSopenharmony_ci      if (v >= 64)
3773370b324cSopenharmony_ci        return E_INVALIDARG;
3774370b324cSopenharmony_ci      complexInCommands = (UInt64)1 << v;
3775370b324cSopenharmony_ci      continue;
3776370b324cSopenharmony_ci    }
3777370b324cSopenharmony_ci
3778370b324cSopenharmony_ci    const bool isCurrent_fixedDict = name.IsEqualTo("df");
3779370b324cSopenharmony_ci    if (isCurrent_fixedDict)
3780370b324cSopenharmony_ci      isFixedDict = true;
3781370b324cSopenharmony_ci    if (isCurrent_fixedDict || name.IsEqualTo("ds"))
3782370b324cSopenharmony_ci    {
3783370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog))
3784370b324cSopenharmony_ci      if (startDicLog > 32)
3785370b324cSopenharmony_ci        return E_INVALIDARG;
3786370b324cSopenharmony_ci      startDicLog_Defined = true;
3787370b324cSopenharmony_ci      continue;
3788370b324cSopenharmony_ci    }
3789370b324cSopenharmony_ci
3790370b324cSopenharmony_ci    if (name.IsEqualTo("mts"))
3791370b324cSopenharmony_ci    {
3792370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start))
3793370b324cSopenharmony_ci      continue;
3794370b324cSopenharmony_ci    }
3795370b324cSopenharmony_ci
3796370b324cSopenharmony_ci    if (name.IsEqualTo("af"))
3797370b324cSopenharmony_ci    {
3798370b324cSopenharmony_ci      UInt32 bundle;
3799370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, bundle))
3800370b324cSopenharmony_ci      if (bundle > 0 && bundle < numCPUs)
3801370b324cSopenharmony_ci      {
3802370b324cSopenharmony_ci        #ifndef Z7_ST
3803370b324cSopenharmony_ci        affinityMode.SetLevels(numCPUs, 2);
3804370b324cSopenharmony_ci        affinityMode.NumBundleThreads = bundle;
3805370b324cSopenharmony_ci        #endif
3806370b324cSopenharmony_ci      }
3807370b324cSopenharmony_ci      continue;
3808370b324cSopenharmony_ci    }
3809370b324cSopenharmony_ci
3810370b324cSopenharmony_ci    if (name.IsEqualTo("freq"))
3811370b324cSopenharmony_ci    {
3812370b324cSopenharmony_ci      UInt32 freq32 = 0;
3813370b324cSopenharmony_ci      RINOK(ParsePropToUInt32(UString(), propVariant, freq32))
3814370b324cSopenharmony_ci      if (freq32 == 0)
3815370b324cSopenharmony_ci        return E_INVALIDARG;
3816370b324cSopenharmony_ci      specifiedFreq = (UInt64)freq32 * 1000000;
3817370b324cSopenharmony_ci
3818370b324cSopenharmony_ci      if (printCallback)
3819370b324cSopenharmony_ci      {
3820370b324cSopenharmony_ci        printCallback->Print("freq=");
3821370b324cSopenharmony_ci        PrintNumber(*printCallback, freq32, 0);
3822370b324cSopenharmony_ci        printCallback->NewLine();
3823370b324cSopenharmony_ci      }
3824370b324cSopenharmony_ci
3825370b324cSopenharmony_ci      continue;
3826370b324cSopenharmony_ci    }
3827370b324cSopenharmony_ci
3828370b324cSopenharmony_ci    if (name.IsPrefixedBy_Ascii_NoCase("mt"))
3829370b324cSopenharmony_ci    {
3830370b324cSopenharmony_ci      const UString s = name.Ptr(2);
3831370b324cSopenharmony_ci      if (s.IsEqualTo("*")
3832370b324cSopenharmony_ci          || (s.IsEmpty()
3833370b324cSopenharmony_ci            && propVariant.vt == VT_BSTR
3834370b324cSopenharmony_ci            && StringsAreEqual_Ascii(propVariant.bstrVal, "*")))
3835370b324cSopenharmony_ci      {
3836370b324cSopenharmony_ci        multiThreadTests = true;
3837370b324cSopenharmony_ci        continue;
3838370b324cSopenharmony_ci      }
3839370b324cSopenharmony_ci      #ifndef Z7_ST
3840370b324cSopenharmony_ci      RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified))
3841370b324cSopenharmony_ci      #endif
3842370b324cSopenharmony_ci      continue;
3843370b324cSopenharmony_ci    }
3844370b324cSopenharmony_ci
3845370b324cSopenharmony_ci    RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant))
3846370b324cSopenharmony_ci  }
3847370b324cSopenharmony_ci  }
3848370b324cSopenharmony_ci
3849370b324cSopenharmony_ci  if (printCallback)
3850370b324cSopenharmony_ci  {
3851370b324cSopenharmony_ci    AString s;
3852370b324cSopenharmony_ci
3853370b324cSopenharmony_ci   #ifndef _WIN32
3854370b324cSopenharmony_ci    s += "Compiler: ";
3855370b324cSopenharmony_ci    GetCompiler(s);
3856370b324cSopenharmony_ci    printCallback->Print(s);
3857370b324cSopenharmony_ci    printCallback->NewLine();
3858370b324cSopenharmony_ci    s.Empty();
3859370b324cSopenharmony_ci   #endif
3860370b324cSopenharmony_ci
3861370b324cSopenharmony_ci    GetSystemInfoText(s);
3862370b324cSopenharmony_ci    printCallback->Print(s);
3863370b324cSopenharmony_ci    printCallback->NewLine();
3864370b324cSopenharmony_ci  }
3865370b324cSopenharmony_ci
3866370b324cSopenharmony_ci  if (printCallback)
3867370b324cSopenharmony_ci  {
3868370b324cSopenharmony_ci    printCallback->Print("1T CPU Freq (MHz):");
3869370b324cSopenharmony_ci  }
3870370b324cSopenharmony_ci
3871370b324cSopenharmony_ci  if (printCallback || freqCallback)
3872370b324cSopenharmony_ci  {
3873370b324cSopenharmony_ci    UInt64 numMilCommands = 1 << 6;
3874370b324cSopenharmony_ci    if (specifiedFreq != 0)
3875370b324cSopenharmony_ci    {
3876370b324cSopenharmony_ci      while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
3877370b324cSopenharmony_ci        numMilCommands >>= 1;
3878370b324cSopenharmony_ci    }
3879370b324cSopenharmony_ci
3880370b324cSopenharmony_ci    for (int jj = 0;; jj++)
3881370b324cSopenharmony_ci    {
3882370b324cSopenharmony_ci      if (printCallback)
3883370b324cSopenharmony_ci        RINOK(printCallback->CheckBreak())
3884370b324cSopenharmony_ci
3885370b324cSopenharmony_ci      UInt64 start = ::GetTimeCount();
3886370b324cSopenharmony_ci      UInt32 sum = (UInt32)start;
3887370b324cSopenharmony_ci      sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
3888370b324cSopenharmony_ci      if (sum == 0xF1541213)
3889370b324cSopenharmony_ci        if (printCallback)
3890370b324cSopenharmony_ci          printCallback->Print("");
3891370b324cSopenharmony_ci      const UInt64 realDelta = ::GetTimeCount() - start;
3892370b324cSopenharmony_ci      start = realDelta;
3893370b324cSopenharmony_ci      if (start == 0)
3894370b324cSopenharmony_ci        start = 1;
3895370b324cSopenharmony_ci      if (start > (UInt64)1 << 61)
3896370b324cSopenharmony_ci        start = 1;
3897370b324cSopenharmony_ci      const UInt64 freq = GetFreq();
3898370b324cSopenharmony_ci      // mips is constant in some compilers
3899370b324cSopenharmony_ci      const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, freq, start);
3900370b324cSopenharmony_ci      const UInt64 mipsVal = numMilCommands * freq / start;
3901370b324cSopenharmony_ci      if (printCallback)
3902370b324cSopenharmony_ci      {
3903370b324cSopenharmony_ci        if (realDelta == 0)
3904370b324cSopenharmony_ci        {
3905370b324cSopenharmony_ci          printCallback->Print(" -");
3906370b324cSopenharmony_ci        }
3907370b324cSopenharmony_ci        else
3908370b324cSopenharmony_ci        {
3909370b324cSopenharmony_ci          // PrintNumber(*printCallback, start, 0);
3910370b324cSopenharmony_ci          PrintNumber(*printCallback, mipsVal, 5);
3911370b324cSopenharmony_ci        }
3912370b324cSopenharmony_ci      }
3913370b324cSopenharmony_ci      if (freqCallback)
3914370b324cSopenharmony_ci      {
3915370b324cSopenharmony_ci        RINOK(freqCallback->AddCpuFreq(1, hz, kBenchmarkUsageMult))
3916370b324cSopenharmony_ci      }
3917370b324cSopenharmony_ci
3918370b324cSopenharmony_ci      if (jj >= 1)
3919370b324cSopenharmony_ci      {
3920370b324cSopenharmony_ci        bool needStop = (numMilCommands >= (1 <<
3921370b324cSopenharmony_ci          #ifdef _DEBUG
3922370b324cSopenharmony_ci            7
3923370b324cSopenharmony_ci          #else
3924370b324cSopenharmony_ci            11
3925370b324cSopenharmony_ci          #endif
3926370b324cSopenharmony_ci          ));
3927370b324cSopenharmony_ci        if (start >= freq * 16)
3928370b324cSopenharmony_ci        {
3929370b324cSopenharmony_ci          printCallback->Print(" (Cmplx)");
3930370b324cSopenharmony_ci          if (!freqCallback) // we don't want complexity change for old gui lzma benchmark
3931370b324cSopenharmony_ci          {
3932370b324cSopenharmony_ci            needSetComplexity = true;
3933370b324cSopenharmony_ci          }
3934370b324cSopenharmony_ci          needStop = true;
3935370b324cSopenharmony_ci        }
3936370b324cSopenharmony_ci        if (needSetComplexity)
3937370b324cSopenharmony_ci          SetComplexCommandsMs(testTimeMs, false, mipsVal * 1000000, complexInCommands);
3938370b324cSopenharmony_ci        if (needStop)
3939370b324cSopenharmony_ci          break;
3940370b324cSopenharmony_ci        numMilCommands <<= 1;
3941370b324cSopenharmony_ci      }
3942370b324cSopenharmony_ci    }
3943370b324cSopenharmony_ci    if (freqCallback)
3944370b324cSopenharmony_ci    {
3945370b324cSopenharmony_ci      RINOK(freqCallback->FreqsFinished(1))
3946370b324cSopenharmony_ci    }
3947370b324cSopenharmony_ci  }
3948370b324cSopenharmony_ci
3949370b324cSopenharmony_ci  if (numThreadsSpecified >= 2)
3950370b324cSopenharmony_ci  if (printCallback || freqCallback)
3951370b324cSopenharmony_ci  {
3952370b324cSopenharmony_ci    if (printCallback)
3953370b324cSopenharmony_ci      printCallback->NewLine();
3954370b324cSopenharmony_ci
3955370b324cSopenharmony_ci    /* it can show incorrect frequency for HT threads.
3956370b324cSopenharmony_ci       so we reduce freq test to (numCPUs / 2) */
3957370b324cSopenharmony_ci
3958370b324cSopenharmony_ci    UInt32 numThreads = numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2: numThreadsSpecified;
3959370b324cSopenharmony_ci    if (numThreads < 1)
3960370b324cSopenharmony_ci      numThreads = 1;
3961370b324cSopenharmony_ci
3962370b324cSopenharmony_ci    if (printCallback)
3963370b324cSopenharmony_ci    {
3964370b324cSopenharmony_ci      char s[128];
3965370b324cSopenharmony_ci      ConvertUInt64ToString(numThreads, s);
3966370b324cSopenharmony_ci      printCallback->Print(s);
3967370b324cSopenharmony_ci      printCallback->Print("T CPU Freq (MHz):");
3968370b324cSopenharmony_ci    }
3969370b324cSopenharmony_ci    UInt64 numMilCommands = 1 <<
3970370b324cSopenharmony_ci          #ifdef _DEBUG
3971370b324cSopenharmony_ci            7;
3972370b324cSopenharmony_ci          #else
3973370b324cSopenharmony_ci            10;
3974370b324cSopenharmony_ci          #endif
3975370b324cSopenharmony_ci
3976370b324cSopenharmony_ci    if (specifiedFreq != 0)
3977370b324cSopenharmony_ci    {
3978370b324cSopenharmony_ci      while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
3979370b324cSopenharmony_ci        numMilCommands >>= 1;
3980370b324cSopenharmony_ci    }
3981370b324cSopenharmony_ci
3982370b324cSopenharmony_ci    // for (int jj = 0;; jj++)
3983370b324cSopenharmony_ci    for (;;)
3984370b324cSopenharmony_ci    {
3985370b324cSopenharmony_ci      if (printCallback)
3986370b324cSopenharmony_ci        RINOK(printCallback->CheckBreak())
3987370b324cSopenharmony_ci
3988370b324cSopenharmony_ci      {
3989370b324cSopenharmony_ci        // PrintLeft(f, "CPU", kFieldSize_Name);
3990370b324cSopenharmony_ci
3991370b324cSopenharmony_ci        // UInt32 resVal;
3992370b324cSopenharmony_ci
3993370b324cSopenharmony_ci        CFreqBench fb;
3994370b324cSopenharmony_ci        fb.complexInCommands = numMilCommands * 1000000;
3995370b324cSopenharmony_ci        fb.numThreads = numThreads;
3996370b324cSopenharmony_ci        // showFreq;
3997370b324cSopenharmony_ci        // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
3998370b324cSopenharmony_ci        fb.showFreq = true;
3999370b324cSopenharmony_ci        fb.specifiedFreq = 1;
4000370b324cSopenharmony_ci
4001370b324cSopenharmony_ci        const HRESULT res = fb.FreqBench(NULL /* printCallback */
4002370b324cSopenharmony_ci            #ifndef Z7_ST
4003370b324cSopenharmony_ci              , &affinityMode
4004370b324cSopenharmony_ci            #endif
4005370b324cSopenharmony_ci            );
4006370b324cSopenharmony_ci        RINOK(res)
4007370b324cSopenharmony_ci
4008370b324cSopenharmony_ci        if (freqCallback)
4009370b324cSopenharmony_ci        {
4010370b324cSopenharmony_ci          RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes))
4011370b324cSopenharmony_ci        }
4012370b324cSopenharmony_ci
4013370b324cSopenharmony_ci        if (printCallback)
4014370b324cSopenharmony_ci        {
4015370b324cSopenharmony_ci          /*
4016370b324cSopenharmony_ci          if (realDelta == 0)
4017370b324cSopenharmony_ci          {
4018370b324cSopenharmony_ci            printCallback->Print(" -");
4019370b324cSopenharmony_ci          }
4020370b324cSopenharmony_ci          else
4021370b324cSopenharmony_ci          */
4022370b324cSopenharmony_ci          {
4023370b324cSopenharmony_ci            // PrintNumber(*printCallback, start, 0);
4024370b324cSopenharmony_ci            PrintUsage(*printCallback, fb.UsageRes, 3);
4025370b324cSopenharmony_ci            printCallback->Print("%");
4026370b324cSopenharmony_ci            PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0);
4027370b324cSopenharmony_ci            printCallback->Print("  ");
4028370b324cSopenharmony_ci
4029370b324cSopenharmony_ci            // PrintNumber(*printCallback, fb.UsageRes, 5);
4030370b324cSopenharmony_ci          }
4031370b324cSopenharmony_ci        }
4032370b324cSopenharmony_ci      }
4033370b324cSopenharmony_ci      // if (jj >= 1)
4034370b324cSopenharmony_ci      {
4035370b324cSopenharmony_ci        const bool needStop = (numMilCommands >= (1 <<
4036370b324cSopenharmony_ci          #ifdef _DEBUG
4037370b324cSopenharmony_ci            7
4038370b324cSopenharmony_ci          #else
4039370b324cSopenharmony_ci            11
4040370b324cSopenharmony_ci          #endif
4041370b324cSopenharmony_ci          ));
4042370b324cSopenharmony_ci        if (needStop)
4043370b324cSopenharmony_ci          break;
4044370b324cSopenharmony_ci        numMilCommands <<= 1;
4045370b324cSopenharmony_ci      }
4046370b324cSopenharmony_ci    }
4047370b324cSopenharmony_ci    if (freqCallback)
4048370b324cSopenharmony_ci    {
4049370b324cSopenharmony_ci      RINOK(freqCallback->FreqsFinished(numThreads))
4050370b324cSopenharmony_ci    }
4051370b324cSopenharmony_ci  }
4052370b324cSopenharmony_ci
4053370b324cSopenharmony_ci
4054370b324cSopenharmony_ci  if (printCallback)
4055370b324cSopenharmony_ci  {
4056370b324cSopenharmony_ci    printCallback->NewLine();
4057370b324cSopenharmony_ci    printCallback->NewLine();
4058370b324cSopenharmony_ci    PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
4059370b324cSopenharmony_ci    printCallback->Print(GetProcessThreadsInfo(threadsInfo));
4060370b324cSopenharmony_ci    printCallback->NewLine();
4061370b324cSopenharmony_ci  }
4062370b324cSopenharmony_ci
4063370b324cSopenharmony_ci  if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
4064370b324cSopenharmony_ci    return E_INVALIDARG;
4065370b324cSopenharmony_ci
4066370b324cSopenharmony_ci  UInt64 dict = (UInt64)1 << startDicLog;
4067370b324cSopenharmony_ci  const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict));
4068370b324cSopenharmony_ci
4069370b324cSopenharmony_ci  const unsigned level = method.GetLevel();
4070370b324cSopenharmony_ci
4071370b324cSopenharmony_ci  AString &methodName = method.MethodName;
4072370b324cSopenharmony_ci  const AString original_MethodName = methodName;
4073370b324cSopenharmony_ci  if (methodName.IsEmpty())
4074370b324cSopenharmony_ci    methodName = "LZMA";
4075370b324cSopenharmony_ci
4076370b324cSopenharmony_ci  if (benchCallback)
4077370b324cSopenharmony_ci  {
4078370b324cSopenharmony_ci    CBenchProps benchProps;
4079370b324cSopenharmony_ci    benchProps.SetLzmaCompexity();
4080370b324cSopenharmony_ci    const UInt64 dictSize = method.Get_Lzma_DicSize();
4081370b324cSopenharmony_ci
4082370b324cSopenharmony_ci    size_t uncompressedDataSize;
4083370b324cSopenharmony_ci    if (use_fileData)
4084370b324cSopenharmony_ci    {
4085370b324cSopenharmony_ci      uncompressedDataSize = fileDataBuffer.Size();
4086370b324cSopenharmony_ci    }
4087370b324cSopenharmony_ci    else
4088370b324cSopenharmony_ci    {
4089370b324cSopenharmony_ci      uncompressedDataSize = kAdditionalSize + (size_t)dictSize;
4090370b324cSopenharmony_ci      if (uncompressedDataSize < dictSize)
4091370b324cSopenharmony_ci        return E_INVALIDARG;
4092370b324cSopenharmony_ci    }
4093370b324cSopenharmony_ci
4094370b324cSopenharmony_ci    return MethodBench(
4095370b324cSopenharmony_ci        EXTERNAL_CODECS_LOC_VARS
4096370b324cSopenharmony_ci        complexInCommands,
4097370b324cSopenharmony_ci      #ifndef Z7_ST
4098370b324cSopenharmony_ci        true, numThreadsSpecified,
4099370b324cSopenharmony_ci        &affinityMode,
4100370b324cSopenharmony_ci      #endif
4101370b324cSopenharmony_ci        method,
4102370b324cSopenharmony_ci        uncompressedDataSize, (const Byte *)fileDataBuffer,
4103370b324cSopenharmony_ci        kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
4104370b324cSopenharmony_ci  }
4105370b324cSopenharmony_ci
4106370b324cSopenharmony_ci  if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
4107370b324cSopenharmony_ci    methodName = "crc32";
4108370b324cSopenharmony_ci
4109370b324cSopenharmony_ci  CMethodId hashID;
4110370b324cSopenharmony_ci  const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID);
4111370b324cSopenharmony_ci  int codecIndex = -1;
4112370b324cSopenharmony_ci  bool isFilter = false;
4113370b324cSopenharmony_ci  if (!isHashMethod)
4114370b324cSopenharmony_ci  {
4115370b324cSopenharmony_ci    UInt32 numStreams;
4116370b324cSopenharmony_ci    codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName,
4117370b324cSopenharmony_ci        true,  // encode
4118370b324cSopenharmony_ci        hashID, numStreams, isFilter);
4119370b324cSopenharmony_ci    // we can allow non filter for BW tests
4120370b324cSopenharmony_ci    if (!isFilter) codecIndex = -1;
4121370b324cSopenharmony_ci  }
4122370b324cSopenharmony_ci
4123370b324cSopenharmony_ci  CBenchCallbackToPrint callback;
4124370b324cSopenharmony_ci  callback.Init();
4125370b324cSopenharmony_ci  callback._file = printCallback;
4126370b324cSopenharmony_ci
4127370b324cSopenharmony_ci  if (isHashMethod || codecIndex != -1)
4128370b324cSopenharmony_ci  {
4129370b324cSopenharmony_ci    if (!printCallback)
4130370b324cSopenharmony_ci      return S_FALSE;
4131370b324cSopenharmony_ci    IBenchPrintCallback &f = *printCallback;
4132370b324cSopenharmony_ci
4133370b324cSopenharmony_ci    UInt64 dict64 = dict;
4134370b324cSopenharmony_ci    if (!dictIsDefined)
4135370b324cSopenharmony_ci      dict64 = (1 << 27);
4136370b324cSopenharmony_ci    if (use_fileData)
4137370b324cSopenharmony_ci    {
4138370b324cSopenharmony_ci      if (!dictIsDefined)
4139370b324cSopenharmony_ci        dict64 = fileDataBuffer.Size();
4140370b324cSopenharmony_ci      else if (dict64 > fileDataBuffer.Size())
4141370b324cSopenharmony_ci        dict64 = fileDataBuffer.Size();
4142370b324cSopenharmony_ci    }
4143370b324cSopenharmony_ci
4144370b324cSopenharmony_ci    for (;;)
4145370b324cSopenharmony_ci    {
4146370b324cSopenharmony_ci      const int index = method.FindProp(NCoderPropID::kDictionarySize);
4147370b324cSopenharmony_ci      if (index < 0)
4148370b324cSopenharmony_ci        break;
4149370b324cSopenharmony_ci      method.Props.Delete((unsigned)index);
4150370b324cSopenharmony_ci    }
4151370b324cSopenharmony_ci
4152370b324cSopenharmony_ci    // methodName.RemoveChar(L'-');
4153370b324cSopenharmony_ci    Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method
4154370b324cSopenharmony_ci    const UInt32 *checkSum = NULL;
4155370b324cSopenharmony_ci    int benchIndex = -1;
4156370b324cSopenharmony_ci
4157370b324cSopenharmony_ci    if (isHashMethod)
4158370b324cSopenharmony_ci    {
4159370b324cSopenharmony_ci      for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
4160370b324cSopenharmony_ci      {
4161370b324cSopenharmony_ci        const CBenchHash &h = g_Hash[i];
4162370b324cSopenharmony_ci        AString benchMethod (h.Name);
4163370b324cSopenharmony_ci        AString benchProps;
4164370b324cSopenharmony_ci        const int propPos = benchMethod.Find(':');
4165370b324cSopenharmony_ci        if (propPos >= 0)
4166370b324cSopenharmony_ci        {
4167370b324cSopenharmony_ci          benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4168370b324cSopenharmony_ci          benchMethod.DeleteFrom((unsigned)propPos);
4169370b324cSopenharmony_ci        }
4170370b324cSopenharmony_ci
4171370b324cSopenharmony_ci        if (AreSameMethodNames(benchMethod, methodName))
4172370b324cSopenharmony_ci        {
4173370b324cSopenharmony_ci          const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
4174370b324cSopenharmony_ci          /*
4175370b324cSopenharmony_ci          bool isMainMethod = method.PropsString.IsEmpty();
4176370b324cSopenharmony_ci          if (isMainMethod)
4177370b324cSopenharmony_ci            isMainMethod = !checkSum
4178370b324cSopenharmony_ci                || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8"));
4179370b324cSopenharmony_ci          if (sameProps || isMainMethod)
4180370b324cSopenharmony_ci          */
4181370b324cSopenharmony_ci          {
4182370b324cSopenharmony_ci            complexity = (Int32)h.Complex;
4183370b324cSopenharmony_ci            checkSum = &h.CheckSum;
4184370b324cSopenharmony_ci            if (sameProps)
4185370b324cSopenharmony_ci              break;
4186370b324cSopenharmony_ci            /*
4187370b324cSopenharmony_ci            if property. is not specified, we use the complexity
4188370b324cSopenharmony_ci            for latest fastest method (crc32:64)
4189370b324cSopenharmony_ci            */
4190370b324cSopenharmony_ci          }
4191370b324cSopenharmony_ci        }
4192370b324cSopenharmony_ci      }
4193370b324cSopenharmony_ci      // if (!checkSum) return E_NOTIMPL;
4194370b324cSopenharmony_ci    }
4195370b324cSopenharmony_ci    else
4196370b324cSopenharmony_ci    {
4197370b324cSopenharmony_ci      for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
4198370b324cSopenharmony_ci      {
4199370b324cSopenharmony_ci        const CBenchMethod &bench = g_Bench[i];
4200370b324cSopenharmony_ci        AString benchMethod (bench.Name);
4201370b324cSopenharmony_ci        AString benchProps;
4202370b324cSopenharmony_ci        const int propPos = benchMethod.Find(':');
4203370b324cSopenharmony_ci        if (propPos >= 0)
4204370b324cSopenharmony_ci        {
4205370b324cSopenharmony_ci          benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4206370b324cSopenharmony_ci          benchMethod.DeleteFrom((unsigned)propPos);
4207370b324cSopenharmony_ci        }
4208370b324cSopenharmony_ci
4209370b324cSopenharmony_ci        if (AreSameMethodNames(benchMethod, methodName))
4210370b324cSopenharmony_ci        {
4211370b324cSopenharmony_ci          const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
4212370b324cSopenharmony_ci          // bool isMainMethod = method.PropsString.IsEmpty();
4213370b324cSopenharmony_ci          // if (sameProps || isMainMethod)
4214370b324cSopenharmony_ci          {
4215370b324cSopenharmony_ci            benchIndex = (int)i;
4216370b324cSopenharmony_ci            if (sameProps)
4217370b324cSopenharmony_ci              break;
4218370b324cSopenharmony_ci          }
4219370b324cSopenharmony_ci        }
4220370b324cSopenharmony_ci      }
4221370b324cSopenharmony_ci      // if (benchIndex < 0) return E_NOTIMPL;
4222370b324cSopenharmony_ci    }
4223370b324cSopenharmony_ci
4224370b324cSopenharmony_ci    {
4225370b324cSopenharmony_ci      /* we count usage only for crc and filter. non-filters are not supported */
4226370b324cSopenharmony_ci      UInt64 usage = (1 << 20);
4227370b324cSopenharmony_ci      UInt64 bufSize = dict64;
4228370b324cSopenharmony_ci      UInt32 numBlocks = isHashMethod ? 1 : 3;
4229370b324cSopenharmony_ci      if (use_fileData)
4230370b324cSopenharmony_ci      {
4231370b324cSopenharmony_ci        usage += fileDataBuffer.Size();
4232370b324cSopenharmony_ci        if (bufSize > fileDataBuffer.Size())
4233370b324cSopenharmony_ci          bufSize = fileDataBuffer.Size();
4234370b324cSopenharmony_ci        if (isHashMethod)
4235370b324cSopenharmony_ci        {
4236370b324cSopenharmony_ci          numBlocks = 0;
4237370b324cSopenharmony_ci          #ifndef Z7_ST
4238370b324cSopenharmony_ci          if (numThreadsSpecified != 1)
4239370b324cSopenharmony_ci            numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0);
4240370b324cSopenharmony_ci          #endif
4241370b324cSopenharmony_ci        }
4242370b324cSopenharmony_ci      }
4243370b324cSopenharmony_ci      usage += numThreadsSpecified * bufSize * numBlocks;
4244370b324cSopenharmony_ci      Print_Usage_and_Threads(f, usage, numThreadsSpecified);
4245370b324cSopenharmony_ci    }
4246370b324cSopenharmony_ci
4247370b324cSopenharmony_ci    CUIntVector numThreadsVector;
4248370b324cSopenharmony_ci    {
4249370b324cSopenharmony_ci      unsigned nt = numThreads_Start;
4250370b324cSopenharmony_ci      for (;;)
4251370b324cSopenharmony_ci      {
4252370b324cSopenharmony_ci        if (nt > numThreadsSpecified)
4253370b324cSopenharmony_ci          break;
4254370b324cSopenharmony_ci        numThreadsVector.Add(nt);
4255370b324cSopenharmony_ci        const unsigned next = nt * 2;
4256370b324cSopenharmony_ci        const UInt32 ntHalf= numThreadsSpecified / 2;
4257370b324cSopenharmony_ci        if (ntHalf > nt && ntHalf < next)
4258370b324cSopenharmony_ci          numThreadsVector.Add(ntHalf);
4259370b324cSopenharmony_ci        if (numThreadsSpecified > nt && numThreadsSpecified < next)
4260370b324cSopenharmony_ci          numThreadsVector.Add(numThreadsSpecified);
4261370b324cSopenharmony_ci        nt = next;
4262370b324cSopenharmony_ci      }
4263370b324cSopenharmony_ci    }
4264370b324cSopenharmony_ci
4265370b324cSopenharmony_ci    unsigned numColumns = isHashMethod ? 1 : 2;
4266370b324cSopenharmony_ci    CTempValues speedTotals;
4267370b324cSopenharmony_ci    CTempValues usageTotals;
4268370b324cSopenharmony_ci    {
4269370b324cSopenharmony_ci      const unsigned numItems = numThreadsVector.Size() * numColumns;
4270370b324cSopenharmony_ci      speedTotals.Alloc(numItems);
4271370b324cSopenharmony_ci      usageTotals.Alloc(numItems);
4272370b324cSopenharmony_ci      for (unsigned i = 0; i < numItems; i++)
4273370b324cSopenharmony_ci      {
4274370b324cSopenharmony_ci        speedTotals.Values[i] = 0;
4275370b324cSopenharmony_ci        usageTotals.Values[i] = 0;
4276370b324cSopenharmony_ci      }
4277370b324cSopenharmony_ci    }
4278370b324cSopenharmony_ci
4279370b324cSopenharmony_ci    f.NewLine();
4280370b324cSopenharmony_ci    for (unsigned line = 0; line < 3; line++)
4281370b324cSopenharmony_ci    {
4282370b324cSopenharmony_ci      f.NewLine();
4283370b324cSopenharmony_ci      f.Print(line == 0 ? "THRD" : line == 1 ? "    " : "Size");
4284370b324cSopenharmony_ci      FOR_VECTOR (ti, numThreadsVector)
4285370b324cSopenharmony_ci      {
4286370b324cSopenharmony_ci        if (ti != 0)
4287370b324cSopenharmony_ci          Print_Delimiter(f);
4288370b324cSopenharmony_ci        if (line == 0)
4289370b324cSopenharmony_ci        {
4290370b324cSopenharmony_ci          PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1));
4291370b324cSopenharmony_ci          PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed);
4292370b324cSopenharmony_ci        }
4293370b324cSopenharmony_ci        else
4294370b324cSopenharmony_ci        {
4295370b324cSopenharmony_ci          for (unsigned c = 0; c < numColumns; c++)
4296370b324cSopenharmony_ci          {
4297370b324cSopenharmony_ci            PrintRight(f, line == 1 ? "Usage" : "%",    kFieldSize_Usage + 1);
4298370b324cSopenharmony_ci            PrintRight(f, line == 1 ? "BW"    : "MB/s", kFieldSize_CrcSpeed + 1);
4299370b324cSopenharmony_ci          }
4300370b324cSopenharmony_ci        }
4301370b324cSopenharmony_ci      }
4302370b324cSopenharmony_ci    }
4303370b324cSopenharmony_ci    f.NewLine();
4304370b324cSopenharmony_ci
4305370b324cSopenharmony_ci    UInt64 numSteps = 0;
4306370b324cSopenharmony_ci
4307370b324cSopenharmony_ci    // for (UInt32 iter = 0; iter < numIterations; iter++)
4308370b324cSopenharmony_ci    // {
4309370b324cSopenharmony_ci    unsigned pow = 10; // kNumHashDictBits
4310370b324cSopenharmony_ci    if (startDicLog_Defined)
4311370b324cSopenharmony_ci      pow = startDicLog;
4312370b324cSopenharmony_ci
4313370b324cSopenharmony_ci    // #define NUM_SUB_BITS 2
4314370b324cSopenharmony_ci    // pow <<= NUM_SUB_BITS;
4315370b324cSopenharmony_ci    for (;; pow++)
4316370b324cSopenharmony_ci    {
4317370b324cSopenharmony_ci      const UInt64 bufSize = (UInt64)1 << pow;
4318370b324cSopenharmony_ci      // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS);
4319370b324cSopenharmony_ci      // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS);
4320370b324cSopenharmony_ci
4321370b324cSopenharmony_ci      size_t dataSize = fileDataBuffer.Size();
4322370b324cSopenharmony_ci      if (dataSize > bufSize || !use_fileData)
4323370b324cSopenharmony_ci        dataSize = (size_t)bufSize;
4324370b324cSopenharmony_ci
4325370b324cSopenharmony_ci      for (UInt32 iter = 0; iter < numIterations; iter++)
4326370b324cSopenharmony_ci      {
4327370b324cSopenharmony_ci        Print_Pow(f, pow);
4328370b324cSopenharmony_ci        // PrintNumber(f, bufSize >> 10, 4);
4329370b324cSopenharmony_ci
4330370b324cSopenharmony_ci        FOR_VECTOR (ti, numThreadsVector)
4331370b324cSopenharmony_ci        {
4332370b324cSopenharmony_ci          RINOK(f.CheckBreak())
4333370b324cSopenharmony_ci          const UInt32 numThreads = numThreadsVector[ti];
4334370b324cSopenharmony_ci          if (isHashMethod)
4335370b324cSopenharmony_ci          {
4336370b324cSopenharmony_ci            UInt64 speed = 0;
4337370b324cSopenharmony_ci            UInt64 usage = 0;
4338370b324cSopenharmony_ci            const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
4339370b324cSopenharmony_ci              numThreads,
4340370b324cSopenharmony_ci              dataSize, (const Byte *)fileDataBuffer,
4341370b324cSopenharmony_ci              speed, usage,
4342370b324cSopenharmony_ci              (UInt32)complexity,
4343370b324cSopenharmony_ci              1, // benchWeight,
4344370b324cSopenharmony_ci              (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL,
4345370b324cSopenharmony_ci              method,
4346370b324cSopenharmony_ci              &f,
4347370b324cSopenharmony_ci            #ifndef Z7_ST
4348370b324cSopenharmony_ci              &affinityMode,
4349370b324cSopenharmony_ci            #endif
4350370b324cSopenharmony_ci              false, // showRating
4351370b324cSopenharmony_ci              NULL, false, 0);
4352370b324cSopenharmony_ci            RINOK(res)
4353370b324cSopenharmony_ci
4354370b324cSopenharmony_ci            if (ti != 0)
4355370b324cSopenharmony_ci              Print_Delimiter(f);
4356370b324cSopenharmony_ci
4357370b324cSopenharmony_ci            Bench_BW_Print_Usage_Speed(f, usage, speed);
4358370b324cSopenharmony_ci            speedTotals.Values[ti] += speed;
4359370b324cSopenharmony_ci            usageTotals.Values[ti] += usage;
4360370b324cSopenharmony_ci          }
4361370b324cSopenharmony_ci          else
4362370b324cSopenharmony_ci          {
4363370b324cSopenharmony_ci            {
4364370b324cSopenharmony_ci              unsigned keySize = 32;
4365370b324cSopenharmony_ci                   if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16;
4366370b324cSopenharmony_ci              else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24;
4367370b324cSopenharmony_ci              callback.BenchProps.KeySize = keySize;
4368370b324cSopenharmony_ci            }
4369370b324cSopenharmony_ci
4370370b324cSopenharmony_ci            COneMethodInfo method2 = method;
4371370b324cSopenharmony_ci            unsigned bench_DictBits;
4372370b324cSopenharmony_ci
4373370b324cSopenharmony_ci            if (benchIndex >= 0)
4374370b324cSopenharmony_ci            {
4375370b324cSopenharmony_ci              const CBenchMethod &bench = g_Bench[benchIndex];
4376370b324cSopenharmony_ci              callback.BenchProps.EncComplex = bench.EncComplex;
4377370b324cSopenharmony_ci              callback.BenchProps.DecComplexUnc = bench.DecComplexUnc;
4378370b324cSopenharmony_ci              callback.BenchProps.DecComplexCompr = bench.DecComplexCompr;
4379370b324cSopenharmony_ci              bench_DictBits = bench.DictBits;
4380370b324cSopenharmony_ci              // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug
4381370b324cSopenharmony_ci            }
4382370b324cSopenharmony_ci            else
4383370b324cSopenharmony_ci            {
4384370b324cSopenharmony_ci              bench_DictBits = kOldLzmaDictBits; // = 32 default
4385370b324cSopenharmony_ci              if (isFilter)
4386370b324cSopenharmony_ci              {
4387370b324cSopenharmony_ci                const unsigned k_UnknownCoderComplexity = 4;
4388370b324cSopenharmony_ci                callback.BenchProps.EncComplex = k_UnknownCoderComplexity;
4389370b324cSopenharmony_ci                callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity;
4390370b324cSopenharmony_ci              }
4391370b324cSopenharmony_ci              else
4392370b324cSopenharmony_ci              {
4393370b324cSopenharmony_ci                callback.BenchProps.EncComplex = 1 << 10;
4394370b324cSopenharmony_ci                callback.BenchProps.DecComplexUnc = 1 << 6;
4395370b324cSopenharmony_ci              }
4396370b324cSopenharmony_ci              callback.BenchProps.DecComplexCompr = 0;
4397370b324cSopenharmony_ci            }
4398370b324cSopenharmony_ci            callback.NeedPrint = false;
4399370b324cSopenharmony_ci
4400370b324cSopenharmony_ci            if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
4401370b324cSopenharmony_ci            {
4402370b324cSopenharmony_ci              const NCOM::CPropVariant propVariant = (UInt32)pow;
4403370b324cSopenharmony_ci              RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
4404370b324cSopenharmony_ci            }
4405370b324cSopenharmony_ci
4406370b324cSopenharmony_ci            const HRESULT res = MethodBench(
4407370b324cSopenharmony_ci                EXTERNAL_CODECS_LOC_VARS
4408370b324cSopenharmony_ci                complexInCommands,
4409370b324cSopenharmony_ci              #ifndef Z7_ST
4410370b324cSopenharmony_ci                false, // oldLzmaBenchMode
4411370b324cSopenharmony_ci                numThreadsVector[ti],
4412370b324cSopenharmony_ci                &affinityMode,
4413370b324cSopenharmony_ci              #endif
4414370b324cSopenharmony_ci                method2,
4415370b324cSopenharmony_ci                dataSize, (const Byte *)fileDataBuffer,
4416370b324cSopenharmony_ci                bench_DictBits,
4417370b324cSopenharmony_ci                printCallback,
4418370b324cSopenharmony_ci                &callback,
4419370b324cSopenharmony_ci                &callback.BenchProps);
4420370b324cSopenharmony_ci            RINOK(res)
4421370b324cSopenharmony_ci
4422370b324cSopenharmony_ci            if (ti != 0)
4423370b324cSopenharmony_ci              Print_Delimiter(f);
4424370b324cSopenharmony_ci
4425370b324cSopenharmony_ci            for (unsigned i = 0; i < 2; i++)
4426370b324cSopenharmony_ci            {
4427370b324cSopenharmony_ci              const CBenchInfo &bi = callback.BenchInfo_Results[i];
4428370b324cSopenharmony_ci              const UInt64 usage = bi.GetUsage();
4429370b324cSopenharmony_ci              const UInt64 speed = bi.GetUnpackSizeSpeed();
4430370b324cSopenharmony_ci              usageTotals.Values[ti * 2 + i] += usage;
4431370b324cSopenharmony_ci              speedTotals.Values[ti * 2 + i] += speed;
4432370b324cSopenharmony_ci              Bench_BW_Print_Usage_Speed(f, usage, speed);
4433370b324cSopenharmony_ci            }
4434370b324cSopenharmony_ci          }
4435370b324cSopenharmony_ci        }
4436370b324cSopenharmony_ci
4437370b324cSopenharmony_ci        f.NewLine();
4438370b324cSopenharmony_ci        numSteps++;
4439370b324cSopenharmony_ci      }
4440370b324cSopenharmony_ci      if (dataSize >= dict64)
4441370b324cSopenharmony_ci        break;
4442370b324cSopenharmony_ci    }
4443370b324cSopenharmony_ci
4444370b324cSopenharmony_ci    if (numSteps != 0)
4445370b324cSopenharmony_ci    {
4446370b324cSopenharmony_ci      f.Print("Avg:");
4447370b324cSopenharmony_ci      for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++)
4448370b324cSopenharmony_ci      {
4449370b324cSopenharmony_ci        if (ti != 0)
4450370b324cSopenharmony_ci          Print_Delimiter(f);
4451370b324cSopenharmony_ci        for (unsigned i = 0; i < numColumns; i++)
4452370b324cSopenharmony_ci          Bench_BW_Print_Usage_Speed(f,
4453370b324cSopenharmony_ci              usageTotals.Values[ti * numColumns + i] / numSteps,
4454370b324cSopenharmony_ci              speedTotals.Values[ti * numColumns + i] / numSteps);
4455370b324cSopenharmony_ci      }
4456370b324cSopenharmony_ci      f.NewLine();
4457370b324cSopenharmony_ci    }
4458370b324cSopenharmony_ci
4459370b324cSopenharmony_ci    return S_OK;
4460370b324cSopenharmony_ci  }
4461370b324cSopenharmony_ci
4462370b324cSopenharmony_ci  bool use2Columns = false;
4463370b324cSopenharmony_ci
4464370b324cSopenharmony_ci  bool totalBenchMode = false;
4465370b324cSopenharmony_ci  bool onlyHashBench = false;
4466370b324cSopenharmony_ci  if (methodName.IsEqualTo_Ascii_NoCase("hash"))
4467370b324cSopenharmony_ci  {
4468370b324cSopenharmony_ci    onlyHashBench = true;
4469370b324cSopenharmony_ci    methodName = "*";
4470370b324cSopenharmony_ci    totalBenchMode = true;
4471370b324cSopenharmony_ci  }
4472370b324cSopenharmony_ci  else if (methodName.Find('*') >= 0)
4473370b324cSopenharmony_ci    totalBenchMode = true;
4474370b324cSopenharmony_ci
4475370b324cSopenharmony_ci  // ---------- Threads loop ----------
4476370b324cSopenharmony_ci  for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++)
4477370b324cSopenharmony_ci  {
4478370b324cSopenharmony_ci
4479370b324cSopenharmony_ci  UInt32 numThreads = numThreadsSpecified;
4480370b324cSopenharmony_ci
4481370b324cSopenharmony_ci  if (!multiThreadTests)
4482370b324cSopenharmony_ci  {
4483370b324cSopenharmony_ci    if (threadsPassIndex != 0)
4484370b324cSopenharmony_ci      break;
4485370b324cSopenharmony_ci  }
4486370b324cSopenharmony_ci  else
4487370b324cSopenharmony_ci  {
4488370b324cSopenharmony_ci    numThreads = 1;
4489370b324cSopenharmony_ci    if (threadsPassIndex != 0)
4490370b324cSopenharmony_ci    {
4491370b324cSopenharmony_ci      if (numCPUs < 2)
4492370b324cSopenharmony_ci        break;
4493370b324cSopenharmony_ci      numThreads = numCPUs;
4494370b324cSopenharmony_ci      if (threadsPassIndex == 1)
4495370b324cSopenharmony_ci      {
4496370b324cSopenharmony_ci        if (numCPUs >= 4)
4497370b324cSopenharmony_ci          numThreads = numCPUs / 2;
4498370b324cSopenharmony_ci      }
4499370b324cSopenharmony_ci      else if (numCPUs < 4)
4500370b324cSopenharmony_ci        break;
4501370b324cSopenharmony_ci    }
4502370b324cSopenharmony_ci  }
4503370b324cSopenharmony_ci
4504370b324cSopenharmony_ci  IBenchPrintCallback &f = *printCallback;
4505370b324cSopenharmony_ci
4506370b324cSopenharmony_ci  if (threadsPassIndex > 0)
4507370b324cSopenharmony_ci  {
4508370b324cSopenharmony_ci    f.NewLine();
4509370b324cSopenharmony_ci    f.NewLine();
4510370b324cSopenharmony_ci  }
4511370b324cSopenharmony_ci
4512370b324cSopenharmony_ci  if (!dictIsDefined && !onlyHashBench)
4513370b324cSopenharmony_ci  {
4514370b324cSopenharmony_ci    const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
4515370b324cSopenharmony_ci    unsigned dicSizeLog = dicSizeLog_Main;
4516370b324cSopenharmony_ci
4517370b324cSopenharmony_ci    #ifdef UNDER_CE
4518370b324cSopenharmony_ci    dicSizeLog = (UInt64)1 << 20;
4519370b324cSopenharmony_ci    #endif
4520370b324cSopenharmony_ci
4521370b324cSopenharmony_ci    if (ramSize_Defined)
4522370b324cSopenharmony_ci    for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
4523370b324cSopenharmony_ci      if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
4524370b324cSopenharmony_ci        break;
4525370b324cSopenharmony_ci
4526370b324cSopenharmony_ci    dict = (UInt64)1 << dicSizeLog;
4527370b324cSopenharmony_ci
4528370b324cSopenharmony_ci    if (totalBenchMode && dicSizeLog != dicSizeLog_Main)
4529370b324cSopenharmony_ci    {
4530370b324cSopenharmony_ci      f.Print("Dictionary reduced to: ");
4531370b324cSopenharmony_ci      PrintNumber(f, dicSizeLog, 1);
4532370b324cSopenharmony_ci      f.NewLine();
4533370b324cSopenharmony_ci    }
4534370b324cSopenharmony_ci  }
4535370b324cSopenharmony_ci
4536370b324cSopenharmony_ci  Print_Usage_and_Threads(f,
4537370b324cSopenharmony_ci      onlyHashBench ?
4538370b324cSopenharmony_ci        GetBenchMemoryUsage_Hash(numThreads, dict) :
4539370b324cSopenharmony_ci        GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode),
4540370b324cSopenharmony_ci      numThreads);
4541370b324cSopenharmony_ci
4542370b324cSopenharmony_ci  f.NewLine();
4543370b324cSopenharmony_ci
4544370b324cSopenharmony_ci  f.NewLine();
4545370b324cSopenharmony_ci
4546370b324cSopenharmony_ci  if (totalBenchMode)
4547370b324cSopenharmony_ci  {
4548370b324cSopenharmony_ci    callback.NameFieldSize = kFieldSize_Name;
4549370b324cSopenharmony_ci    use2Columns = false;
4550370b324cSopenharmony_ci  }
4551370b324cSopenharmony_ci  else
4552370b324cSopenharmony_ci  {
4553370b324cSopenharmony_ci    callback.NameFieldSize = kFieldSize_SmallName;
4554370b324cSopenharmony_ci    use2Columns = true;
4555370b324cSopenharmony_ci  }
4556370b324cSopenharmony_ci  callback.Use2Columns = use2Columns;
4557370b324cSopenharmony_ci
4558370b324cSopenharmony_ci  bool showFreq = false;
4559370b324cSopenharmony_ci  UInt64 cpuFreq = 0;
4560370b324cSopenharmony_ci
4561370b324cSopenharmony_ci  if (totalBenchMode)
4562370b324cSopenharmony_ci  {
4563370b324cSopenharmony_ci    showFreq = true;
4564370b324cSopenharmony_ci  }
4565370b324cSopenharmony_ci
4566370b324cSopenharmony_ci  unsigned fileldSize = kFieldSize_TotalSize;
4567370b324cSopenharmony_ci  if (showFreq)
4568370b324cSopenharmony_ci    fileldSize += kFieldSize_EUAndEffec;
4569370b324cSopenharmony_ci
4570370b324cSopenharmony_ci  if (use2Columns)
4571370b324cSopenharmony_ci  {
4572370b324cSopenharmony_ci    PrintSpaces(f, callback.NameFieldSize);
4573370b324cSopenharmony_ci    PrintRight(f, "Compressing", fileldSize);
4574370b324cSopenharmony_ci    f.Print(kSep);
4575370b324cSopenharmony_ci    PrintRight(f, "Decompressing", fileldSize);
4576370b324cSopenharmony_ci  }
4577370b324cSopenharmony_ci  f.NewLine();
4578370b324cSopenharmony_ci  PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize);
4579370b324cSopenharmony_ci
4580370b324cSopenharmony_ci  int j;
4581370b324cSopenharmony_ci
4582370b324cSopenharmony_ci  for (j = 0; j < 2; j++)
4583370b324cSopenharmony_ci  {
4584370b324cSopenharmony_ci    PrintRight(f, "Speed", kFieldSize_Speed + 1);
4585370b324cSopenharmony_ci    PrintRight(f, "Usage", kFieldSize_Usage + 1);
4586370b324cSopenharmony_ci    PrintRight(f, "R/U", kFieldSize_RU + 1);
4587370b324cSopenharmony_ci    PrintRight(f, "Rating", kFieldSize_Rating + 1);
4588370b324cSopenharmony_ci    if (showFreq)
4589370b324cSopenharmony_ci    {
4590370b324cSopenharmony_ci      PrintRight(f, "E/U", kFieldSize_EU + 1);
4591370b324cSopenharmony_ci      PrintRight(f, "Effec", kFieldSize_Effec + 1);
4592370b324cSopenharmony_ci    }
4593370b324cSopenharmony_ci    if (!use2Columns)
4594370b324cSopenharmony_ci      break;
4595370b324cSopenharmony_ci    if (j == 0)
4596370b324cSopenharmony_ci      f.Print(kSep);
4597370b324cSopenharmony_ci  }
4598370b324cSopenharmony_ci
4599370b324cSopenharmony_ci  f.NewLine();
4600370b324cSopenharmony_ci  PrintSpaces(f, callback.NameFieldSize);
4601370b324cSopenharmony_ci
4602370b324cSopenharmony_ci  for (j = 0; j < 2; j++)
4603370b324cSopenharmony_ci  {
4604370b324cSopenharmony_ci    PrintRight(f, "KiB/s", kFieldSize_Speed + 1);
4605370b324cSopenharmony_ci    PrintRight(f, "%", kFieldSize_Usage + 1);
4606370b324cSopenharmony_ci    PrintRight(f, "MIPS", kFieldSize_RU + 1);
4607370b324cSopenharmony_ci    PrintRight(f, "MIPS", kFieldSize_Rating + 1);
4608370b324cSopenharmony_ci    if (showFreq)
4609370b324cSopenharmony_ci    {
4610370b324cSopenharmony_ci      PrintRight(f, "%", kFieldSize_EU + 1);
4611370b324cSopenharmony_ci      PrintRight(f, "%", kFieldSize_Effec + 1);
4612370b324cSopenharmony_ci    }
4613370b324cSopenharmony_ci    if (!use2Columns)
4614370b324cSopenharmony_ci      break;
4615370b324cSopenharmony_ci    if (j == 0)
4616370b324cSopenharmony_ci      f.Print(kSep);
4617370b324cSopenharmony_ci  }
4618370b324cSopenharmony_ci
4619370b324cSopenharmony_ci  f.NewLine();
4620370b324cSopenharmony_ci  f.NewLine();
4621370b324cSopenharmony_ci
4622370b324cSopenharmony_ci  if (specifiedFreq != 0)
4623370b324cSopenharmony_ci    cpuFreq = specifiedFreq;
4624370b324cSopenharmony_ci
4625370b324cSopenharmony_ci  // bool showTotalSpeed = false;
4626370b324cSopenharmony_ci
4627370b324cSopenharmony_ci  if (totalBenchMode)
4628370b324cSopenharmony_ci  {
4629370b324cSopenharmony_ci    for (UInt32 i = 0; i < numIterations; i++)
4630370b324cSopenharmony_ci    {
4631370b324cSopenharmony_ci      if (i != 0)
4632370b324cSopenharmony_ci        printCallback->NewLine();
4633370b324cSopenharmony_ci
4634370b324cSopenharmony_ci      const unsigned kNumCpuTests = 3;
4635370b324cSopenharmony_ci      for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++)
4636370b324cSopenharmony_ci      {
4637370b324cSopenharmony_ci        PrintLeft(f, "CPU", kFieldSize_Name);
4638370b324cSopenharmony_ci
4639370b324cSopenharmony_ci        // UInt32 resVal;
4640370b324cSopenharmony_ci
4641370b324cSopenharmony_ci        CFreqBench fb;
4642370b324cSopenharmony_ci        fb.complexInCommands = complexInCommands;
4643370b324cSopenharmony_ci        fb.numThreads = numThreads;
4644370b324cSopenharmony_ci        // showFreq;
4645370b324cSopenharmony_ci        fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
4646370b324cSopenharmony_ci        fb.specifiedFreq = specifiedFreq;
4647370b324cSopenharmony_ci
4648370b324cSopenharmony_ci        const HRESULT res = fb.FreqBench(printCallback
4649370b324cSopenharmony_ci            #ifndef Z7_ST
4650370b324cSopenharmony_ci              , &affinityMode
4651370b324cSopenharmony_ci            #endif
4652370b324cSopenharmony_ci            );
4653370b324cSopenharmony_ci        RINOK(res)
4654370b324cSopenharmony_ci
4655370b324cSopenharmony_ci        cpuFreq = fb.CpuFreqRes;
4656370b324cSopenharmony_ci        callback.NewLine();
4657370b324cSopenharmony_ci
4658370b324cSopenharmony_ci        if (specifiedFreq != 0)
4659370b324cSopenharmony_ci          cpuFreq = specifiedFreq;
4660370b324cSopenharmony_ci
4661370b324cSopenharmony_ci        if (testTimeMs >= 1000)
4662370b324cSopenharmony_ci        if (freqTest == kNumCpuTests - 1)
4663370b324cSopenharmony_ci        {
4664370b324cSopenharmony_ci          // SetComplexCommandsMs(testTimeMs, specifiedFreq != 0, cpuFreq, complexInCommands);
4665370b324cSopenharmony_ci        }
4666370b324cSopenharmony_ci      }
4667370b324cSopenharmony_ci      callback.NewLine();
4668370b324cSopenharmony_ci
4669370b324cSopenharmony_ci      // return S_OK; // change it
4670370b324cSopenharmony_ci
4671370b324cSopenharmony_ci      callback.SetFreq(true, cpuFreq);
4672370b324cSopenharmony_ci
4673370b324cSopenharmony_ci      if (!onlyHashBench)
4674370b324cSopenharmony_ci      {
4675370b324cSopenharmony_ci        size_t dataSize = (size_t)dict;
4676370b324cSopenharmony_ci        if (use_fileData)
4677370b324cSopenharmony_ci        {
4678370b324cSopenharmony_ci          dataSize = fileDataBuffer.Size();
4679370b324cSopenharmony_ci          if (dictIsDefined && dataSize > dict)
4680370b324cSopenharmony_ci            dataSize = (size_t)dict;
4681370b324cSopenharmony_ci        }
4682370b324cSopenharmony_ci
4683370b324cSopenharmony_ci        const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS
4684370b324cSopenharmony_ci            method, complexInCommands,
4685370b324cSopenharmony_ci          #ifndef Z7_ST
4686370b324cSopenharmony_ci            numThreads,
4687370b324cSopenharmony_ci            &affinityMode,
4688370b324cSopenharmony_ci          #endif
4689370b324cSopenharmony_ci            dictIsDefined || use_fileData, // forceUnpackSize
4690370b324cSopenharmony_ci            dataSize,
4691370b324cSopenharmony_ci            (const Byte *)fileDataBuffer,
4692370b324cSopenharmony_ci            printCallback, &callback);
4693370b324cSopenharmony_ci        RINOK(res)
4694370b324cSopenharmony_ci      }
4695370b324cSopenharmony_ci
4696370b324cSopenharmony_ci      {
4697370b324cSopenharmony_ci        size_t dataSize = (size_t)1 << kNumHashDictBits;
4698370b324cSopenharmony_ci        if (dictIsDefined)
4699370b324cSopenharmony_ci        {
4700370b324cSopenharmony_ci          dataSize = (size_t)dict;
4701370b324cSopenharmony_ci          if (dataSize != dict)
4702370b324cSopenharmony_ci            return E_OUTOFMEMORY;
4703370b324cSopenharmony_ci        }
4704370b324cSopenharmony_ci        if (use_fileData)
4705370b324cSopenharmony_ci        {
4706370b324cSopenharmony_ci          dataSize = fileDataBuffer.Size();
4707370b324cSopenharmony_ci          if (dictIsDefined && dataSize > dict)
4708370b324cSopenharmony_ci            dataSize = (size_t)dict;
4709370b324cSopenharmony_ci        }
4710370b324cSopenharmony_ci
4711370b324cSopenharmony_ci        const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS
4712370b324cSopenharmony_ci            method, complexInCommands,
4713370b324cSopenharmony_ci            numThreads,
4714370b324cSopenharmony_ci            dataSize, (const Byte *)fileDataBuffer,
4715370b324cSopenharmony_ci            printCallback, &callback,
4716370b324cSopenharmony_ci        #ifndef Z7_ST
4717370b324cSopenharmony_ci          &affinityMode,
4718370b324cSopenharmony_ci        #endif
4719370b324cSopenharmony_ci          &callback.EncodeRes, true, cpuFreq);
4720370b324cSopenharmony_ci        RINOK(res)
4721370b324cSopenharmony_ci      }
4722370b324cSopenharmony_ci
4723370b324cSopenharmony_ci      callback.NewLine();
4724370b324cSopenharmony_ci      {
4725370b324cSopenharmony_ci        PrintLeft(f, "CPU", kFieldSize_Name);
4726370b324cSopenharmony_ci
4727370b324cSopenharmony_ci        CFreqBench fb;
4728370b324cSopenharmony_ci        fb.complexInCommands = complexInCommands;
4729370b324cSopenharmony_ci        fb.numThreads = numThreads;
4730370b324cSopenharmony_ci        // showFreq;
4731370b324cSopenharmony_ci        fb.showFreq = (specifiedFreq != 0);
4732370b324cSopenharmony_ci        fb.specifiedFreq = specifiedFreq;
4733370b324cSopenharmony_ci
4734370b324cSopenharmony_ci        const HRESULT res = fb.FreqBench(printCallback
4735370b324cSopenharmony_ci          #ifndef Z7_ST
4736370b324cSopenharmony_ci            , &affinityMode
4737370b324cSopenharmony_ci          #endif
4738370b324cSopenharmony_ci          );
4739370b324cSopenharmony_ci        RINOK(res)
4740370b324cSopenharmony_ci        callback.NewLine();
4741370b324cSopenharmony_ci      }
4742370b324cSopenharmony_ci    }
4743370b324cSopenharmony_ci  }
4744370b324cSopenharmony_ci  else
4745370b324cSopenharmony_ci  {
4746370b324cSopenharmony_ci    needSetComplexity = true;
4747370b324cSopenharmony_ci    if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
4748370b324cSopenharmony_ci    {
4749370b324cSopenharmony_ci      unsigned i;
4750370b324cSopenharmony_ci      for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
4751370b324cSopenharmony_ci      {
4752370b324cSopenharmony_ci        const CBenchMethod &h = g_Bench[i];
4753370b324cSopenharmony_ci        AString benchMethod (h.Name);
4754370b324cSopenharmony_ci        AString benchProps;
4755370b324cSopenharmony_ci        const int propPos = benchMethod.Find(':');
4756370b324cSopenharmony_ci        if (propPos >= 0)
4757370b324cSopenharmony_ci        {
4758370b324cSopenharmony_ci          benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4759370b324cSopenharmony_ci          benchMethod.DeleteFrom((unsigned)propPos);
4760370b324cSopenharmony_ci        }
4761370b324cSopenharmony_ci
4762370b324cSopenharmony_ci        if (AreSameMethodNames(benchMethod, methodName))
4763370b324cSopenharmony_ci        {
4764370b324cSopenharmony_ci          if (benchProps.IsEmpty()
4765370b324cSopenharmony_ci              || (benchProps == "x5" && method.PropsString.IsEmpty())
4766370b324cSopenharmony_ci              || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps))
4767370b324cSopenharmony_ci          {
4768370b324cSopenharmony_ci            callback.BenchProps.EncComplex = h.EncComplex;
4769370b324cSopenharmony_ci            callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
4770370b324cSopenharmony_ci            callback.BenchProps.DecComplexUnc = h.DecComplexUnc;
4771370b324cSopenharmony_ci            needSetComplexity = false;
4772370b324cSopenharmony_ci            break;
4773370b324cSopenharmony_ci          }
4774370b324cSopenharmony_ci        }
4775370b324cSopenharmony_ci      }
4776370b324cSopenharmony_ci      /*
4777370b324cSopenharmony_ci      if (i == Z7_ARRAY_SIZE(g_Bench))
4778370b324cSopenharmony_ci        return E_NOTIMPL;
4779370b324cSopenharmony_ci      */
4780370b324cSopenharmony_ci    }
4781370b324cSopenharmony_ci    if (needSetComplexity)
4782370b324cSopenharmony_ci      callback.BenchProps.SetLzmaCompexity();
4783370b324cSopenharmony_ci
4784370b324cSopenharmony_ci  if (startDicLog < kBenchMinDicLogSize)
4785370b324cSopenharmony_ci    startDicLog = kBenchMinDicLogSize;
4786370b324cSopenharmony_ci
4787370b324cSopenharmony_ci  for (unsigned i = 0; i < numIterations; i++)
4788370b324cSopenharmony_ci  {
4789370b324cSopenharmony_ci    unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog;
4790370b324cSopenharmony_ci    if (!multiDict)
4791370b324cSopenharmony_ci      pow = 32;
4792370b324cSopenharmony_ci    while (GetDictSizeFromLog(pow) > dict && pow > 0)
4793370b324cSopenharmony_ci      pow--;
4794370b324cSopenharmony_ci    for (; GetDictSizeFromLog(pow) <= dict; pow++)
4795370b324cSopenharmony_ci    {
4796370b324cSopenharmony_ci      Print_Pow(f, pow);
4797370b324cSopenharmony_ci      callback.DictSize = (UInt64)1 << pow;
4798370b324cSopenharmony_ci
4799370b324cSopenharmony_ci      COneMethodInfo method2 = method;
4800370b324cSopenharmony_ci
4801370b324cSopenharmony_ci      if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
4802370b324cSopenharmony_ci      {
4803370b324cSopenharmony_ci        // We add dictionary size property.
4804370b324cSopenharmony_ci        // method2 can have two different dictionary size properties.
4805370b324cSopenharmony_ci        // And last property is main.
4806370b324cSopenharmony_ci        NCOM::CPropVariant propVariant = (UInt32)pow;
4807370b324cSopenharmony_ci        RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
4808370b324cSopenharmony_ci      }
4809370b324cSopenharmony_ci
4810370b324cSopenharmony_ci      size_t uncompressedDataSize;
4811370b324cSopenharmony_ci      if (use_fileData)
4812370b324cSopenharmony_ci      {
4813370b324cSopenharmony_ci        uncompressedDataSize = fileDataBuffer.Size();
4814370b324cSopenharmony_ci      }
4815370b324cSopenharmony_ci      else
4816370b324cSopenharmony_ci      {
4817370b324cSopenharmony_ci        uncompressedDataSize = (size_t)callback.DictSize;
4818370b324cSopenharmony_ci        if (uncompressedDataSize != callback.DictSize)
4819370b324cSopenharmony_ci          return E_OUTOFMEMORY;
4820370b324cSopenharmony_ci        if (uncompressedDataSize >= (1 << 18))
4821370b324cSopenharmony_ci          uncompressedDataSize += kAdditionalSize;
4822370b324cSopenharmony_ci      }
4823370b324cSopenharmony_ci
4824370b324cSopenharmony_ci      const HRESULT res = MethodBench(
4825370b324cSopenharmony_ci          EXTERNAL_CODECS_LOC_VARS
4826370b324cSopenharmony_ci          complexInCommands,
4827370b324cSopenharmony_ci        #ifndef Z7_ST
4828370b324cSopenharmony_ci          true, numThreads,
4829370b324cSopenharmony_ci          &affinityMode,
4830370b324cSopenharmony_ci        #endif
4831370b324cSopenharmony_ci          method2,
4832370b324cSopenharmony_ci          uncompressedDataSize, (const Byte *)fileDataBuffer,
4833370b324cSopenharmony_ci          kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
4834370b324cSopenharmony_ci      f.NewLine();
4835370b324cSopenharmony_ci      RINOK(res)
4836370b324cSopenharmony_ci      if (!multiDict)
4837370b324cSopenharmony_ci        break;
4838370b324cSopenharmony_ci    }
4839370b324cSopenharmony_ci  }
4840370b324cSopenharmony_ci  }
4841370b324cSopenharmony_ci
4842370b324cSopenharmony_ci  PrintChars(f, '-', callback.NameFieldSize + fileldSize);
4843370b324cSopenharmony_ci
4844370b324cSopenharmony_ci  if (use2Columns)
4845370b324cSopenharmony_ci  {
4846370b324cSopenharmony_ci    f.Print(kSep);
4847370b324cSopenharmony_ci    PrintChars(f, '-', fileldSize);
4848370b324cSopenharmony_ci  }
4849370b324cSopenharmony_ci
4850370b324cSopenharmony_ci  f.NewLine();
4851370b324cSopenharmony_ci
4852370b324cSopenharmony_ci  if (use2Columns)
4853370b324cSopenharmony_ci  {
4854370b324cSopenharmony_ci    PrintLeft(f, "Avr:", callback.NameFieldSize);
4855370b324cSopenharmony_ci    PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes);
4856370b324cSopenharmony_ci    f.Print(kSep);
4857370b324cSopenharmony_ci    PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes);
4858370b324cSopenharmony_ci    f.NewLine();
4859370b324cSopenharmony_ci  }
4860370b324cSopenharmony_ci
4861370b324cSopenharmony_ci  PrintLeft(f, "Tot:", callback.NameFieldSize);
4862370b324cSopenharmony_ci  CTotalBenchRes midRes;
4863370b324cSopenharmony_ci  midRes = callback.EncodeRes;
4864370b324cSopenharmony_ci  midRes.Update_With_Res(callback.DecodeRes);
4865370b324cSopenharmony_ci
4866370b324cSopenharmony_ci  // midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
4867370b324cSopenharmony_ci  PrintTotals(f, showFreq, cpuFreq, false, midRes);
4868370b324cSopenharmony_ci  f.NewLine();
4869370b324cSopenharmony_ci
4870370b324cSopenharmony_ci  }
4871370b324cSopenharmony_ci  return S_OK;
4872370b324cSopenharmony_ci}
4873