xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/Bench.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Bench.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
8*f6dc9357SAndroid Build Coastguard Worker #define USE_POSIX_TIME
9*f6dc9357SAndroid Build Coastguard Worker #define USE_POSIX_TIME2
10*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME
13*f6dc9357SAndroid Build Coastguard Worker #include <time.h>
14*f6dc9357SAndroid Build Coastguard Worker #include <unistd.h>
15*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME2
16*f6dc9357SAndroid Build Coastguard Worker #include <sys/time.h>
17*f6dc9357SAndroid Build Coastguard Worker #include <sys/times.h>
18*f6dc9357SAndroid Build Coastguard Worker #endif
19*f6dc9357SAndroid Build Coastguard Worker #endif // USE_POSIX_TIME
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
22*f6dc9357SAndroid Build Coastguard Worker #define USE_ALLOCA
23*f6dc9357SAndroid Build Coastguard Worker #endif
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_ALLOCA
26*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
27*f6dc9357SAndroid Build Coastguard Worker #include <malloc.h>
28*f6dc9357SAndroid Build Coastguard Worker #else
29*f6dc9357SAndroid Build Coastguard Worker #include <stdlib.h>
30*f6dc9357SAndroid Build Coastguard Worker #endif
31*f6dc9357SAndroid Build Coastguard Worker #define BENCH_ALLOCA_VALUE(index) (((index) * 64 * 21) & 0x7FF)
32*f6dc9357SAndroid Build Coastguard Worker #endif
33*f6dc9357SAndroid Build Coastguard Worker 
34*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/7zCrc.h"
35*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/RotateDefs.h"
36*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
37*f6dc9357SAndroid Build Coastguard Worker 
38*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
39*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Synchronization.h"
40*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Thread.h"
41*f6dc9357SAndroid Build Coastguard Worker #endif
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
44*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
45*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/SystemInfo.h"
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyBuffer2.h"
48*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
49*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
50*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringToInt.h"
51*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MethodProps.h"
54*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamObjects.h"
55*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker #include "Bench.h"
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
60*f6dc9357SAndroid Build Coastguard Worker 
61*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
62*f6dc9357SAndroid Build Coastguard Worker static const UInt32 k_LZMA = 0x030101;
63*f6dc9357SAndroid Build Coastguard Worker #endif
64*f6dc9357SAndroid Build Coastguard Worker 
65*f6dc9357SAndroid Build Coastguard Worker static const UInt64 kComplexInCommands = (UInt64)1 <<
66*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
67*f6dc9357SAndroid Build Coastguard Worker     31;
68*f6dc9357SAndroid Build Coastguard Worker   #else
69*f6dc9357SAndroid Build Coastguard Worker     34;
70*f6dc9357SAndroid Build Coastguard Worker   #endif
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kComplexInMs = 4000;
73*f6dc9357SAndroid Build Coastguard Worker 
SetComplexCommandsMs(UInt32 complexInMs,bool isSpecifiedFreq,UInt64 cpuFreq,UInt64 & complexInCommands)74*f6dc9357SAndroid Build Coastguard Worker static void SetComplexCommandsMs(UInt32 complexInMs,
75*f6dc9357SAndroid Build Coastguard Worker     bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands)
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker   complexInCommands = kComplexInCommands;
78*f6dc9357SAndroid Build Coastguard Worker   const UInt64 kMinFreq = (UInt64)1000000 * 4;
79*f6dc9357SAndroid Build Coastguard Worker   const UInt64 kMaxFreq = (UInt64)1000000 * 20000;
80*f6dc9357SAndroid Build Coastguard Worker   if (cpuFreq < kMinFreq && !isSpecifiedFreq)
81*f6dc9357SAndroid Build Coastguard Worker     cpuFreq = kMinFreq;
82*f6dc9357SAndroid Build Coastguard Worker   if (cpuFreq < kMaxFreq || isSpecifiedFreq)
83*f6dc9357SAndroid Build Coastguard Worker   {
84*f6dc9357SAndroid Build Coastguard Worker     if (complexInMs != 0)
85*f6dc9357SAndroid Build Coastguard Worker       complexInCommands = complexInMs * cpuFreq / 1000;
86*f6dc9357SAndroid Build Coastguard Worker     else
87*f6dc9357SAndroid Build Coastguard Worker       complexInCommands = cpuFreq >> 2;
88*f6dc9357SAndroid Build Coastguard Worker   }
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker // const UInt64 kBenchmarkUsageMult = 1000000; // for debug
92*f6dc9357SAndroid Build Coastguard Worker static const unsigned kBenchmarkUsageMultBits = 16;
93*f6dc9357SAndroid Build Coastguard Worker static const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits;
94*f6dc9357SAndroid Build Coastguard Worker 
Benchmark_GetUsage_Percents(UInt64 usage)95*f6dc9357SAndroid Build Coastguard Worker UInt64 Benchmark_GetUsage_Percents(UInt64 usage)
96*f6dc9357SAndroid Build Coastguard Worker {
97*f6dc9357SAndroid Build Coastguard Worker   return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult;
98*f6dc9357SAndroid Build Coastguard Worker }
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumHashDictBits = 17;
101*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker static const unsigned kOldLzmaDictBits = 32;
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker // static const size_t kAdditionalSize = (size_t)1 << 32; // for debug
106*f6dc9357SAndroid Build Coastguard Worker static const size_t kAdditionalSize = (size_t)1 << 16;
107*f6dc9357SAndroid Build Coastguard Worker static const size_t kCompressedAdditionalSize = 1 << 10;
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kMaxMethodPropSize = 1 << 6;
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker 
112*f6dc9357SAndroid Build Coastguard Worker #define ALLOC_WITH_HRESULT(_buffer_, _size_) \
113*f6dc9357SAndroid Build Coastguard Worker   { (_buffer_)->Alloc(_size_); \
114*f6dc9357SAndroid Build Coastguard Worker   if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; }
115*f6dc9357SAndroid Build Coastguard Worker 
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker class CBaseRandomGenerator
118*f6dc9357SAndroid Build Coastguard Worker {
119*f6dc9357SAndroid Build Coastguard Worker   UInt32 A1;
120*f6dc9357SAndroid Build Coastguard Worker   UInt32 A2;
121*f6dc9357SAndroid Build Coastguard Worker   UInt32 Salt;
122*f6dc9357SAndroid Build Coastguard Worker public:
CBaseRandomGenerator(UInt32 salt=0)123*f6dc9357SAndroid Build Coastguard Worker   CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); }
Init()124*f6dc9357SAndroid Build Coastguard Worker   void Init() { A1 = 362436069; A2 = 521288629;}
125*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
GetRnd()126*f6dc9357SAndroid Build Coastguard Worker   UInt32 GetRnd()
127*f6dc9357SAndroid Build Coastguard Worker   {
128*f6dc9357SAndroid Build Coastguard Worker #if 0
129*f6dc9357SAndroid Build Coastguard Worker     // for debug:
130*f6dc9357SAndroid Build Coastguard Worker     return 0x0c080400;
131*f6dc9357SAndroid Build Coastguard Worker     // return 0;
132*f6dc9357SAndroid Build Coastguard Worker #else
133*f6dc9357SAndroid Build Coastguard Worker     return Salt ^
134*f6dc9357SAndroid Build Coastguard Worker     (
135*f6dc9357SAndroid Build Coastguard Worker       ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
136*f6dc9357SAndroid Build Coastguard Worker       ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) )
137*f6dc9357SAndroid Build Coastguard Worker     );
138*f6dc9357SAndroid Build Coastguard Worker #endif
139*f6dc9357SAndroid Build Coastguard Worker   }
140*f6dc9357SAndroid Build Coastguard Worker };
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker static const size_t k_RandBuf_AlignMask = 4 - 1;
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
RandGen_BufAfterPad(Byte * buf,size_t size)146*f6dc9357SAndroid Build Coastguard Worker static void RandGen_BufAfterPad(Byte *buf, size_t size)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker   CBaseRandomGenerator RG;
149*f6dc9357SAndroid Build Coastguard Worker   for (size_t i = 0; i < size; i += 4)
150*f6dc9357SAndroid Build Coastguard Worker   {
151*f6dc9357SAndroid Build Coastguard Worker     const UInt32 v = RG.GetRnd();
152*f6dc9357SAndroid Build Coastguard Worker     SetUi32a(buf + i, v)
153*f6dc9357SAndroid Build Coastguard Worker   }
154*f6dc9357SAndroid Build Coastguard Worker   /*
155*f6dc9357SAndroid Build Coastguard Worker   UInt32 v = RG.GetRnd();
156*f6dc9357SAndroid Build Coastguard Worker   for (; i < size; i++)
157*f6dc9357SAndroid Build Coastguard Worker   {
158*f6dc9357SAndroid Build Coastguard Worker     buf[i] = (Byte)v;
159*f6dc9357SAndroid Build Coastguard Worker     v >>= 8;
160*f6dc9357SAndroid Build Coastguard Worker   }
161*f6dc9357SAndroid Build Coastguard Worker   */
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker class CBenchRandomGenerator: public CMidAlignedBuffer
166*f6dc9357SAndroid Build Coastguard Worker {
GetVal(UInt32 & res,unsigned numBits)167*f6dc9357SAndroid Build Coastguard Worker   static UInt32 GetVal(UInt32 &res, unsigned numBits)
168*f6dc9357SAndroid Build Coastguard Worker   {
169*f6dc9357SAndroid Build Coastguard Worker     const UInt32 val = res & (((UInt32)1 << numBits) - 1);
170*f6dc9357SAndroid Build Coastguard Worker     res >>= numBits;
171*f6dc9357SAndroid Build Coastguard Worker     return val;
172*f6dc9357SAndroid Build Coastguard Worker   }
173*f6dc9357SAndroid Build Coastguard Worker 
GetLen(UInt32 & r)174*f6dc9357SAndroid Build Coastguard Worker   static UInt32 GetLen(UInt32 &r)
175*f6dc9357SAndroid Build Coastguard Worker   {
176*f6dc9357SAndroid Build Coastguard Worker     const unsigned len = (unsigned)GetVal(r, 2);
177*f6dc9357SAndroid Build Coastguard Worker     return GetVal(r, 1 + len);
178*f6dc9357SAndroid Build Coastguard Worker   }
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker public:
181*f6dc9357SAndroid Build Coastguard Worker 
GenerateSimpleRandom(UInt32 salt)182*f6dc9357SAndroid Build Coastguard Worker   void GenerateSimpleRandom(UInt32 salt)
183*f6dc9357SAndroid Build Coastguard Worker   {
184*f6dc9357SAndroid Build Coastguard Worker     CBaseRandomGenerator rg(salt);
185*f6dc9357SAndroid Build Coastguard Worker     const size_t bufSize = Size();
186*f6dc9357SAndroid Build Coastguard Worker     Byte *buf = (Byte *)*this;
187*f6dc9357SAndroid Build Coastguard Worker     for (size_t i = 0; i < bufSize; i++)
188*f6dc9357SAndroid Build Coastguard Worker       buf[i] = (Byte)rg.GetRnd();
189*f6dc9357SAndroid Build Coastguard Worker   }
190*f6dc9357SAndroid Build Coastguard Worker 
GenerateLz(unsigned dictBits,UInt32 salt)191*f6dc9357SAndroid Build Coastguard Worker   void GenerateLz(unsigned dictBits, UInt32 salt)
192*f6dc9357SAndroid Build Coastguard Worker   {
193*f6dc9357SAndroid Build Coastguard Worker     CBaseRandomGenerator rg(salt);
194*f6dc9357SAndroid Build Coastguard Worker     size_t pos = 0;
195*f6dc9357SAndroid Build Coastguard Worker     size_t rep0 = 1;
196*f6dc9357SAndroid Build Coastguard Worker     const size_t bufSize = Size();
197*f6dc9357SAndroid Build Coastguard Worker     Byte *buf = (Byte *)*this;
198*f6dc9357SAndroid Build Coastguard Worker     unsigned posBits = 1;
199*f6dc9357SAndroid Build Coastguard Worker 
200*f6dc9357SAndroid Build Coastguard Worker     // printf("\n dictBits = %d\n", (UInt32)dictBits);
201*f6dc9357SAndroid Build Coastguard Worker     // printf("\n bufSize = 0x%p\n", (const void *)bufSize);
202*f6dc9357SAndroid Build Coastguard Worker 
203*f6dc9357SAndroid Build Coastguard Worker     while (pos < bufSize)
204*f6dc9357SAndroid Build Coastguard Worker     {
205*f6dc9357SAndroid Build Coastguard Worker       /*
206*f6dc9357SAndroid Build Coastguard Worker       if (pos >= ((UInt32)1 << 31))
207*f6dc9357SAndroid Build Coastguard Worker         printf(" %x\n", pos);
208*f6dc9357SAndroid Build Coastguard Worker       */
209*f6dc9357SAndroid Build Coastguard Worker       UInt32 r = rg.GetRnd();
210*f6dc9357SAndroid Build Coastguard Worker       if (GetVal(r, 1) == 0 || pos < 1024)
211*f6dc9357SAndroid Build Coastguard Worker         buf[pos++] = (Byte)(r & 0xFF);
212*f6dc9357SAndroid Build Coastguard Worker       else
213*f6dc9357SAndroid Build Coastguard Worker       {
214*f6dc9357SAndroid Build Coastguard Worker         UInt32 len;
215*f6dc9357SAndroid Build Coastguard Worker         len = 1 + GetLen(r);
216*f6dc9357SAndroid Build Coastguard Worker 
217*f6dc9357SAndroid Build Coastguard Worker         if (GetVal(r, 3) != 0)
218*f6dc9357SAndroid Build Coastguard Worker         {
219*f6dc9357SAndroid Build Coastguard Worker           len += GetLen(r);
220*f6dc9357SAndroid Build Coastguard Worker 
221*f6dc9357SAndroid Build Coastguard Worker           while (((size_t)1 << posBits) < pos)
222*f6dc9357SAndroid Build Coastguard Worker             posBits++;
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker           unsigned numBitsMax = dictBits;
225*f6dc9357SAndroid Build Coastguard Worker           if (numBitsMax > posBits)
226*f6dc9357SAndroid Build Coastguard Worker             numBitsMax = posBits;
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker           const unsigned kAddBits = 6;
229*f6dc9357SAndroid Build Coastguard Worker           unsigned numLogBits = 5;
230*f6dc9357SAndroid Build Coastguard Worker           if (numBitsMax <= (1 << 4) - 1 + kAddBits)
231*f6dc9357SAndroid Build Coastguard Worker             numLogBits = 4;
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker           for (;;)
234*f6dc9357SAndroid Build Coastguard Worker           {
235*f6dc9357SAndroid Build Coastguard Worker             const UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
236*f6dc9357SAndroid Build Coastguard Worker             r = rg.GetRnd();
237*f6dc9357SAndroid Build Coastguard Worker             if (ppp > numBitsMax)
238*f6dc9357SAndroid Build Coastguard Worker               continue;
239*f6dc9357SAndroid Build Coastguard Worker             // rep0 = GetVal(r, ppp);
240*f6dc9357SAndroid Build Coastguard Worker             rep0 = r & (((size_t)1 << ppp) - 1);
241*f6dc9357SAndroid Build Coastguard Worker             if (rep0 < pos)
242*f6dc9357SAndroid Build Coastguard Worker               break;
243*f6dc9357SAndroid Build Coastguard Worker             r = rg.GetRnd();
244*f6dc9357SAndroid Build Coastguard Worker           }
245*f6dc9357SAndroid Build Coastguard Worker           rep0++;
246*f6dc9357SAndroid Build Coastguard Worker         }
247*f6dc9357SAndroid Build Coastguard Worker 
248*f6dc9357SAndroid Build Coastguard Worker         // len *= 300; // for debug
249*f6dc9357SAndroid Build Coastguard Worker         {
250*f6dc9357SAndroid Build Coastguard Worker           const size_t rem = bufSize - pos;
251*f6dc9357SAndroid Build Coastguard Worker           if (len > rem)
252*f6dc9357SAndroid Build Coastguard Worker             len = (UInt32)rem;
253*f6dc9357SAndroid Build Coastguard Worker         }
254*f6dc9357SAndroid Build Coastguard Worker         Byte *dest = buf + pos;
255*f6dc9357SAndroid Build Coastguard Worker         const Byte *src = dest - rep0;
256*f6dc9357SAndroid Build Coastguard Worker         pos += len;
257*f6dc9357SAndroid Build Coastguard Worker         for (UInt32 i = 0; i < len; i++)
258*f6dc9357SAndroid Build Coastguard Worker           *dest++ = *src++;
259*f6dc9357SAndroid Build Coastguard Worker       }
260*f6dc9357SAndroid Build Coastguard Worker     }
261*f6dc9357SAndroid Build Coastguard Worker     // printf("\n CRC = %x\n", CrcCalc(buf, bufSize));
262*f6dc9357SAndroid Build Coastguard Worker   }
263*f6dc9357SAndroid Build Coastguard Worker };
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_NOQIB_1(
267*f6dc9357SAndroid Build Coastguard Worker   CBenchmarkInStream
268*f6dc9357SAndroid Build Coastguard Worker   , ISequentialInStream
269*f6dc9357SAndroid Build Coastguard Worker )
270*f6dc9357SAndroid Build Coastguard Worker   const Byte *Data;
271*f6dc9357SAndroid Build Coastguard Worker   size_t Pos;
272*f6dc9357SAndroid Build Coastguard Worker   size_t Size;
273*f6dc9357SAndroid Build Coastguard Worker public:
274*f6dc9357SAndroid Build Coastguard Worker   void Init(const Byte *data, size_t size)
275*f6dc9357SAndroid Build Coastguard Worker   {
276*f6dc9357SAndroid Build Coastguard Worker     Data = data;
277*f6dc9357SAndroid Build Coastguard Worker     Size = size;
278*f6dc9357SAndroid Build Coastguard Worker     Pos = 0;
279*f6dc9357SAndroid Build Coastguard Worker   }
280*f6dc9357SAndroid Build Coastguard Worker   bool WasFinished() const { return Pos == Size; }
281*f6dc9357SAndroid Build Coastguard Worker };
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kMaxBlockSize = (1 << 20);
286*f6dc9357SAndroid Build Coastguard Worker   if (size > kMaxBlockSize)
287*f6dc9357SAndroid Build Coastguard Worker     size = kMaxBlockSize;
288*f6dc9357SAndroid Build Coastguard Worker   const size_t remain = Size - Pos;
289*f6dc9357SAndroid Build Coastguard Worker   if (size > remain)
290*f6dc9357SAndroid Build Coastguard Worker     size = (UInt32)remain;
291*f6dc9357SAndroid Build Coastguard Worker 
292*f6dc9357SAndroid Build Coastguard Worker   if (size)
293*f6dc9357SAndroid Build Coastguard Worker     memcpy(data, Data + Pos, size);
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker   Pos += size;
296*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
297*f6dc9357SAndroid Build Coastguard Worker     *processedSize = size;
298*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
299*f6dc9357SAndroid Build Coastguard Worker }
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker 
302*f6dc9357SAndroid Build Coastguard Worker class CBenchmarkOutStream Z7_final:
303*f6dc9357SAndroid Build Coastguard Worker   public ISequentialOutStream,
304*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp,
305*f6dc9357SAndroid Build Coastguard Worker   public CMidAlignedBuffer
306*f6dc9357SAndroid Build Coastguard Worker {
307*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_UNKNOWN_IMP_0
308*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(ISequentialOutStream)
309*f6dc9357SAndroid Build Coastguard Worker   // bool _overflow;
310*f6dc9357SAndroid Build Coastguard Worker public:
311*f6dc9357SAndroid Build Coastguard Worker   size_t Pos;
312*f6dc9357SAndroid Build Coastguard Worker   bool RealCopy;
313*f6dc9357SAndroid Build Coastguard Worker   bool CalcCrc;
314*f6dc9357SAndroid Build Coastguard Worker   UInt32 Crc;
315*f6dc9357SAndroid Build Coastguard Worker 
316*f6dc9357SAndroid Build Coastguard Worker   // CBenchmarkOutStream(): _overflow(false) {}
317*f6dc9357SAndroid Build Coastguard Worker   void Init(bool realCopy, bool calcCrc)
318*f6dc9357SAndroid Build Coastguard Worker   {
319*f6dc9357SAndroid Build Coastguard Worker     Crc = CRC_INIT_VAL;
320*f6dc9357SAndroid Build Coastguard Worker     RealCopy = realCopy;
321*f6dc9357SAndroid Build Coastguard Worker     CalcCrc = calcCrc;
322*f6dc9357SAndroid Build Coastguard Worker     // _overflow = false;
323*f6dc9357SAndroid Build Coastguard Worker     Pos = 0;
324*f6dc9357SAndroid Build Coastguard Worker   }
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker   void InitCrc()
327*f6dc9357SAndroid Build Coastguard Worker   {
328*f6dc9357SAndroid Build Coastguard Worker     Crc = CRC_INIT_VAL;
329*f6dc9357SAndroid Build Coastguard Worker   }
330*f6dc9357SAndroid Build Coastguard Worker 
331*f6dc9357SAndroid Build Coastguard Worker   void Calc(const void *data, size_t size)
332*f6dc9357SAndroid Build Coastguard Worker   {
333*f6dc9357SAndroid Build Coastguard Worker     Crc = CrcUpdate(Crc, data, size);
334*f6dc9357SAndroid Build Coastguard Worker   }
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker   size_t GetPos() const { return Pos; }
337*f6dc9357SAndroid Build Coastguard Worker 
338*f6dc9357SAndroid Build Coastguard Worker   // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
339*f6dc9357SAndroid Build Coastguard Worker };
340*f6dc9357SAndroid Build Coastguard Worker 
341*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
342*f6dc9357SAndroid Build Coastguard Worker {
343*f6dc9357SAndroid Build Coastguard Worker   size_t curSize = Size() - Pos;
344*f6dc9357SAndroid Build Coastguard Worker   if (curSize > size)
345*f6dc9357SAndroid Build Coastguard Worker     curSize = size;
346*f6dc9357SAndroid Build Coastguard Worker   if (curSize != 0)
347*f6dc9357SAndroid Build Coastguard Worker   {
348*f6dc9357SAndroid Build Coastguard Worker     if (RealCopy)
349*f6dc9357SAndroid Build Coastguard Worker       memcpy(((Byte *)*this) + Pos, data, curSize);
350*f6dc9357SAndroid Build Coastguard Worker     if (CalcCrc)
351*f6dc9357SAndroid Build Coastguard Worker       Calc(data, curSize);
352*f6dc9357SAndroid Build Coastguard Worker     Pos += curSize;
353*f6dc9357SAndroid Build Coastguard Worker   }
354*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
355*f6dc9357SAndroid Build Coastguard Worker     *processedSize = (UInt32)curSize;
356*f6dc9357SAndroid Build Coastguard Worker   if (curSize != size)
357*f6dc9357SAndroid Build Coastguard Worker   {
358*f6dc9357SAndroid Build Coastguard Worker     // _overflow = true;
359*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
360*f6dc9357SAndroid Build Coastguard Worker   }
361*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
362*f6dc9357SAndroid Build Coastguard Worker }
363*f6dc9357SAndroid Build Coastguard Worker 
364*f6dc9357SAndroid Build Coastguard Worker 
365*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_NOQIB_1(
366*f6dc9357SAndroid Build Coastguard Worker   CCrcOutStream
367*f6dc9357SAndroid Build Coastguard Worker   , ISequentialOutStream
368*f6dc9357SAndroid Build Coastguard Worker )
369*f6dc9357SAndroid Build Coastguard Worker public:
370*f6dc9357SAndroid Build Coastguard Worker   bool CalcCrc;
371*f6dc9357SAndroid Build Coastguard Worker   UInt32 Crc;
372*f6dc9357SAndroid Build Coastguard Worker   UInt64 Pos;
373*f6dc9357SAndroid Build Coastguard Worker 
374*f6dc9357SAndroid Build Coastguard Worker   CCrcOutStream(): CalcCrc(true) {}
375*f6dc9357SAndroid Build Coastguard Worker   void Init() { Crc = CRC_INIT_VAL; Pos = 0; }
376*f6dc9357SAndroid Build Coastguard Worker   void Calc(const void *data, size_t size)
377*f6dc9357SAndroid Build Coastguard Worker   {
378*f6dc9357SAndroid Build Coastguard Worker     Crc = CrcUpdate(Crc, data, size);
379*f6dc9357SAndroid Build Coastguard Worker   }
380*f6dc9357SAndroid Build Coastguard Worker };
381*f6dc9357SAndroid Build Coastguard Worker 
382*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
383*f6dc9357SAndroid Build Coastguard Worker {
384*f6dc9357SAndroid Build Coastguard Worker   if (CalcCrc)
385*f6dc9357SAndroid Build Coastguard Worker     Calc(data, size);
386*f6dc9357SAndroid Build Coastguard Worker   Pos += size;
387*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
388*f6dc9357SAndroid Build Coastguard Worker     *processedSize = size;
389*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
390*f6dc9357SAndroid Build Coastguard Worker }
391*f6dc9357SAndroid Build Coastguard Worker 
392*f6dc9357SAndroid Build Coastguard Worker // #include "../../../../C/My_sys_time.h"
393*f6dc9357SAndroid Build Coastguard Worker 
394*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetTimeCount()
395*f6dc9357SAndroid Build Coastguard Worker {
396*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_POSIX_TIME
397*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_POSIX_TIME2
398*f6dc9357SAndroid Build Coastguard Worker   timeval v;
399*f6dc9357SAndroid Build Coastguard Worker   if (gettimeofday(&v, NULL) == 0)
400*f6dc9357SAndroid Build Coastguard Worker     return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec;
401*f6dc9357SAndroid Build Coastguard Worker   return (UInt64)time(NULL) * 1000000;
402*f6dc9357SAndroid Build Coastguard Worker   #else
403*f6dc9357SAndroid Build Coastguard Worker   return time(NULL);
404*f6dc9357SAndroid Build Coastguard Worker   #endif
405*f6dc9357SAndroid Build Coastguard Worker   #else
406*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER value;
407*f6dc9357SAndroid Build Coastguard Worker   if (::QueryPerformanceCounter(&value))
408*f6dc9357SAndroid Build Coastguard Worker     return (UInt64)value.QuadPart;
409*f6dc9357SAndroid Build Coastguard Worker   return GetTickCount();
410*f6dc9357SAndroid Build Coastguard Worker   #endif
411*f6dc9357SAndroid Build Coastguard Worker }
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetFreq()
414*f6dc9357SAndroid Build Coastguard Worker {
415*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_POSIX_TIME
416*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_POSIX_TIME2
417*f6dc9357SAndroid Build Coastguard Worker   return 1000000;
418*f6dc9357SAndroid Build Coastguard Worker   #else
419*f6dc9357SAndroid Build Coastguard Worker   return 1;
420*f6dc9357SAndroid Build Coastguard Worker   #endif
421*f6dc9357SAndroid Build Coastguard Worker   #else
422*f6dc9357SAndroid Build Coastguard Worker   LARGE_INTEGER value;
423*f6dc9357SAndroid Build Coastguard Worker   if (::QueryPerformanceFrequency(&value))
424*f6dc9357SAndroid Build Coastguard Worker     return (UInt64)value.QuadPart;
425*f6dc9357SAndroid Build Coastguard Worker   return 1000;
426*f6dc9357SAndroid Build Coastguard Worker   #endif
427*f6dc9357SAndroid Build Coastguard Worker }
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker 
430*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME
431*f6dc9357SAndroid Build Coastguard Worker 
432*f6dc9357SAndroid Build Coastguard Worker struct CUserTime
433*f6dc9357SAndroid Build Coastguard Worker {
434*f6dc9357SAndroid Build Coastguard Worker   UInt64 Sum;
435*f6dc9357SAndroid Build Coastguard Worker   clock_t Prev;
436*f6dc9357SAndroid Build Coastguard Worker 
437*f6dc9357SAndroid Build Coastguard Worker   void Init()
438*f6dc9357SAndroid Build Coastguard Worker   {
439*f6dc9357SAndroid Build Coastguard Worker     // Prev = clock();
440*f6dc9357SAndroid Build Coastguard Worker     Sum = 0;
441*f6dc9357SAndroid Build Coastguard Worker     Prev = 0;
442*f6dc9357SAndroid Build Coastguard Worker     Update();
443*f6dc9357SAndroid Build Coastguard Worker     Sum = 0;
444*f6dc9357SAndroid Build Coastguard Worker   }
445*f6dc9357SAndroid Build Coastguard Worker 
446*f6dc9357SAndroid Build Coastguard Worker   void Update()
447*f6dc9357SAndroid Build Coastguard Worker   {
448*f6dc9357SAndroid Build Coastguard Worker     tms t;
449*f6dc9357SAndroid Build Coastguard Worker     /* clock_t res = */ times(&t);
450*f6dc9357SAndroid Build Coastguard Worker     clock_t newVal = t.tms_utime + t.tms_stime;
451*f6dc9357SAndroid Build Coastguard Worker     Sum += (UInt64)(newVal - Prev);
452*f6dc9357SAndroid Build Coastguard Worker     Prev = newVal;
453*f6dc9357SAndroid Build Coastguard Worker 
454*f6dc9357SAndroid Build Coastguard Worker     /*
455*f6dc9357SAndroid Build Coastguard Worker     clock_t v = clock();
456*f6dc9357SAndroid Build Coastguard Worker     if (v != -1)
457*f6dc9357SAndroid Build Coastguard Worker     {
458*f6dc9357SAndroid Build Coastguard Worker       Sum += v - Prev;
459*f6dc9357SAndroid Build Coastguard Worker       Prev = v;
460*f6dc9357SAndroid Build Coastguard Worker     }
461*f6dc9357SAndroid Build Coastguard Worker     */
462*f6dc9357SAndroid Build Coastguard Worker   }
463*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetUserTime()
464*f6dc9357SAndroid Build Coastguard Worker   {
465*f6dc9357SAndroid Build Coastguard Worker     Update();
466*f6dc9357SAndroid Build Coastguard Worker     return Sum;
467*f6dc9357SAndroid Build Coastguard Worker   }
468*f6dc9357SAndroid Build Coastguard Worker };
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker #else
471*f6dc9357SAndroid Build Coastguard Worker 
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker struct CUserTime
474*f6dc9357SAndroid Build Coastguard Worker {
475*f6dc9357SAndroid Build Coastguard Worker   bool UseTick;
476*f6dc9357SAndroid Build Coastguard Worker   DWORD Prev_Tick;
477*f6dc9357SAndroid Build Coastguard Worker   UInt64 Prev;
478*f6dc9357SAndroid Build Coastguard Worker   UInt64 Sum;
479*f6dc9357SAndroid Build Coastguard Worker 
480*f6dc9357SAndroid Build Coastguard Worker   void Init()
481*f6dc9357SAndroid Build Coastguard Worker   {
482*f6dc9357SAndroid Build Coastguard Worker     UseTick = false;
483*f6dc9357SAndroid Build Coastguard Worker     Prev_Tick = 0;
484*f6dc9357SAndroid Build Coastguard Worker     Prev = 0;
485*f6dc9357SAndroid Build Coastguard Worker     Sum = 0;
486*f6dc9357SAndroid Build Coastguard Worker     Update();
487*f6dc9357SAndroid Build Coastguard Worker     Sum = 0;
488*f6dc9357SAndroid Build Coastguard Worker   }
489*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetUserTime()
490*f6dc9357SAndroid Build Coastguard Worker   {
491*f6dc9357SAndroid Build Coastguard Worker     Update();
492*f6dc9357SAndroid Build Coastguard Worker     return Sum;
493*f6dc9357SAndroid Build Coastguard Worker   }
494*f6dc9357SAndroid Build Coastguard Worker   void Update();
495*f6dc9357SAndroid Build Coastguard Worker };
496*f6dc9357SAndroid Build Coastguard Worker 
497*f6dc9357SAndroid Build Coastguard Worker static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
498*f6dc9357SAndroid Build Coastguard Worker 
499*f6dc9357SAndroid Build Coastguard Worker void CUserTime::Update()
500*f6dc9357SAndroid Build Coastguard Worker {
501*f6dc9357SAndroid Build Coastguard Worker   DWORD new_Tick = GetTickCount();
502*f6dc9357SAndroid Build Coastguard Worker   FILETIME creationTime, exitTime, kernelTime, userTime;
503*f6dc9357SAndroid Build Coastguard Worker   if (!UseTick &&
504*f6dc9357SAndroid Build Coastguard Worker       #ifdef UNDER_CE
505*f6dc9357SAndroid Build Coastguard Worker         ::GetThreadTimes(::GetCurrentThread()
506*f6dc9357SAndroid Build Coastguard Worker       #else
507*f6dc9357SAndroid Build Coastguard Worker         ::GetProcessTimes(::GetCurrentProcess()
508*f6dc9357SAndroid Build Coastguard Worker       #endif
509*f6dc9357SAndroid Build Coastguard Worker       , &creationTime, &exitTime, &kernelTime, &userTime))
510*f6dc9357SAndroid Build Coastguard Worker   {
511*f6dc9357SAndroid Build Coastguard Worker     UInt64 newVal = GetTime64(userTime) + GetTime64(kernelTime);
512*f6dc9357SAndroid Build Coastguard Worker     Sum += newVal - Prev;
513*f6dc9357SAndroid Build Coastguard Worker     Prev = newVal;
514*f6dc9357SAndroid Build Coastguard Worker   }
515*f6dc9357SAndroid Build Coastguard Worker   else
516*f6dc9357SAndroid Build Coastguard Worker   {
517*f6dc9357SAndroid Build Coastguard Worker     UseTick = true;
518*f6dc9357SAndroid Build Coastguard Worker     Sum += (UInt64)(new_Tick - (DWORD)Prev_Tick) * 10000;
519*f6dc9357SAndroid Build Coastguard Worker   }
520*f6dc9357SAndroid Build Coastguard Worker   Prev_Tick = new_Tick;
521*f6dc9357SAndroid Build Coastguard Worker }
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker 
524*f6dc9357SAndroid Build Coastguard Worker #endif
525*f6dc9357SAndroid Build Coastguard Worker 
526*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetUserFreq()
527*f6dc9357SAndroid Build Coastguard Worker {
528*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_POSIX_TIME
529*f6dc9357SAndroid Build Coastguard Worker   // return CLOCKS_PER_SEC;
530*f6dc9357SAndroid Build Coastguard Worker   return (UInt64)sysconf(_SC_CLK_TCK);
531*f6dc9357SAndroid Build Coastguard Worker   #else
532*f6dc9357SAndroid Build Coastguard Worker   return 10000000;
533*f6dc9357SAndroid Build Coastguard Worker   #endif
534*f6dc9357SAndroid Build Coastguard Worker }
535*f6dc9357SAndroid Build Coastguard Worker 
536*f6dc9357SAndroid Build Coastguard Worker class CBenchProgressStatus Z7_final
537*f6dc9357SAndroid Build Coastguard Worker {
538*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
539*f6dc9357SAndroid Build Coastguard Worker   NSynchronization::CCriticalSection CS;
540*f6dc9357SAndroid Build Coastguard Worker   #endif
541*f6dc9357SAndroid Build Coastguard Worker public:
542*f6dc9357SAndroid Build Coastguard Worker   HRESULT Res;
543*f6dc9357SAndroid Build Coastguard Worker   bool EncodeMode;
544*f6dc9357SAndroid Build Coastguard Worker   void SetResult(HRESULT res)
545*f6dc9357SAndroid Build Coastguard Worker   {
546*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
547*f6dc9357SAndroid Build Coastguard Worker     NSynchronization::CCriticalSectionLock lock(CS);
548*f6dc9357SAndroid Build Coastguard Worker     #endif
549*f6dc9357SAndroid Build Coastguard Worker     Res = res;
550*f6dc9357SAndroid Build Coastguard Worker   }
551*f6dc9357SAndroid Build Coastguard Worker   HRESULT GetResult()
552*f6dc9357SAndroid Build Coastguard Worker   {
553*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
554*f6dc9357SAndroid Build Coastguard Worker     NSynchronization::CCriticalSectionLock lock(CS);
555*f6dc9357SAndroid Build Coastguard Worker     #endif
556*f6dc9357SAndroid Build Coastguard Worker     return Res;
557*f6dc9357SAndroid Build Coastguard Worker   }
558*f6dc9357SAndroid Build Coastguard Worker };
559*f6dc9357SAndroid Build Coastguard Worker 
560*f6dc9357SAndroid Build Coastguard Worker struct CBenchInfoCalc
561*f6dc9357SAndroid Build Coastguard Worker {
562*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo BenchInfo;
563*f6dc9357SAndroid Build Coastguard Worker   CUserTime UserTime;
564*f6dc9357SAndroid Build Coastguard Worker 
565*f6dc9357SAndroid Build Coastguard Worker   void SetStartTime();
566*f6dc9357SAndroid Build Coastguard Worker   void SetFinishTime(CBenchInfo &dest);
567*f6dc9357SAndroid Build Coastguard Worker };
568*f6dc9357SAndroid Build Coastguard Worker 
569*f6dc9357SAndroid Build Coastguard Worker void CBenchInfoCalc::SetStartTime()
570*f6dc9357SAndroid Build Coastguard Worker {
571*f6dc9357SAndroid Build Coastguard Worker   BenchInfo.GlobalFreq = GetFreq();
572*f6dc9357SAndroid Build Coastguard Worker   BenchInfo.UserFreq = GetUserFreq();
573*f6dc9357SAndroid Build Coastguard Worker   BenchInfo.GlobalTime = ::GetTimeCount();
574*f6dc9357SAndroid Build Coastguard Worker   BenchInfo.UserTime = 0;
575*f6dc9357SAndroid Build Coastguard Worker   UserTime.Init();
576*f6dc9357SAndroid Build Coastguard Worker }
577*f6dc9357SAndroid Build Coastguard Worker 
578*f6dc9357SAndroid Build Coastguard Worker void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest)
579*f6dc9357SAndroid Build Coastguard Worker {
580*f6dc9357SAndroid Build Coastguard Worker   dest = BenchInfo;
581*f6dc9357SAndroid Build Coastguard Worker   dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime;
582*f6dc9357SAndroid Build Coastguard Worker   dest.UserTime = UserTime.GetUserTime();
583*f6dc9357SAndroid Build Coastguard Worker }
584*f6dc9357SAndroid Build Coastguard Worker 
585*f6dc9357SAndroid Build Coastguard Worker class CBenchProgressInfo Z7_final:
586*f6dc9357SAndroid Build Coastguard Worker   public ICompressProgressInfo,
587*f6dc9357SAndroid Build Coastguard Worker   public CMyUnknownImp,
588*f6dc9357SAndroid Build Coastguard Worker   public CBenchInfoCalc
589*f6dc9357SAndroid Build Coastguard Worker {
590*f6dc9357SAndroid Build Coastguard Worker   Z7_COM_UNKNOWN_IMP_0
591*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(ICompressProgressInfo)
592*f6dc9357SAndroid Build Coastguard Worker public:
593*f6dc9357SAndroid Build Coastguard Worker   CBenchProgressStatus *Status;
594*f6dc9357SAndroid Build Coastguard Worker   IBenchCallback *Callback;
595*f6dc9357SAndroid Build Coastguard Worker 
596*f6dc9357SAndroid Build Coastguard Worker   CBenchProgressInfo(): Callback(NULL) {}
597*f6dc9357SAndroid Build Coastguard Worker };
598*f6dc9357SAndroid Build Coastguard Worker 
599*f6dc9357SAndroid Build Coastguard Worker 
600*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
601*f6dc9357SAndroid Build Coastguard Worker {
602*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = Status->GetResult();
603*f6dc9357SAndroid Build Coastguard Worker   if (res != S_OK)
604*f6dc9357SAndroid Build Coastguard Worker     return res;
605*f6dc9357SAndroid Build Coastguard Worker   if (!Callback)
606*f6dc9357SAndroid Build Coastguard Worker     return res;
607*f6dc9357SAndroid Build Coastguard Worker 
608*f6dc9357SAndroid Build Coastguard Worker   /*
609*f6dc9357SAndroid Build Coastguard Worker   static UInt64 inSizePrev = 0;
610*f6dc9357SAndroid Build Coastguard Worker   static UInt64 outSizePrev = 0;
611*f6dc9357SAndroid Build Coastguard Worker   UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0;
612*f6dc9357SAndroid Build Coastguard Worker   if (inSize)   { val1 = *inSize;  delta1 = val1 - inSizePrev;  inSizePrev  = val1; }
613*f6dc9357SAndroid Build Coastguard Worker   if (outSize)  { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2;  }
614*f6dc9357SAndroid Build Coastguard Worker   UInt64 percents = delta2 * 1000;
615*f6dc9357SAndroid Build Coastguard Worker   if (delta1 != 0)
616*f6dc9357SAndroid Build Coastguard Worker     percents /= delta1;
617*f6dc9357SAndroid Build Coastguard Worker   printf("=== %7d %7d     %7d %7d  ratio = %4d\n",
618*f6dc9357SAndroid Build Coastguard Worker       (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10),
619*f6dc9357SAndroid Build Coastguard Worker       (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10),
620*f6dc9357SAndroid Build Coastguard Worker       (unsigned)percents);
621*f6dc9357SAndroid Build Coastguard Worker   */
622*f6dc9357SAndroid Build Coastguard Worker 
623*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo info;
624*f6dc9357SAndroid Build Coastguard Worker   SetFinishTime(info);
625*f6dc9357SAndroid Build Coastguard Worker   if (Status->EncodeMode)
626*f6dc9357SAndroid Build Coastguard Worker   {
627*f6dc9357SAndroid Build Coastguard Worker     info.UnpackSize = BenchInfo.UnpackSize + *inSize;
628*f6dc9357SAndroid Build Coastguard Worker     info.PackSize = BenchInfo.PackSize + *outSize;
629*f6dc9357SAndroid Build Coastguard Worker     res = Callback->SetEncodeResult(info, false);
630*f6dc9357SAndroid Build Coastguard Worker   }
631*f6dc9357SAndroid Build Coastguard Worker   else
632*f6dc9357SAndroid Build Coastguard Worker   {
633*f6dc9357SAndroid Build Coastguard Worker     info.PackSize = BenchInfo.PackSize + *inSize;
634*f6dc9357SAndroid Build Coastguard Worker     info.UnpackSize = BenchInfo.UnpackSize + *outSize;
635*f6dc9357SAndroid Build Coastguard Worker     res = Callback->SetDecodeResult(info, false);
636*f6dc9357SAndroid Build Coastguard Worker   }
637*f6dc9357SAndroid Build Coastguard Worker   if (res != S_OK)
638*f6dc9357SAndroid Build Coastguard Worker     Status->SetResult(res);
639*f6dc9357SAndroid Build Coastguard Worker   return res;
640*f6dc9357SAndroid Build Coastguard Worker }
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSubBits = 8;
643*f6dc9357SAndroid Build Coastguard Worker 
644*f6dc9357SAndroid Build Coastguard Worker static unsigned GetLogSize(UInt64 size)
645*f6dc9357SAndroid Build Coastguard Worker {
646*f6dc9357SAndroid Build Coastguard Worker   unsigned i = 0;
647*f6dc9357SAndroid Build Coastguard Worker   for (;;)
648*f6dc9357SAndroid Build Coastguard Worker   {
649*f6dc9357SAndroid Build Coastguard Worker     i++;  size >>= 1;  if (size == 0) break;
650*f6dc9357SAndroid Build Coastguard Worker   }
651*f6dc9357SAndroid Build Coastguard Worker   return i;
652*f6dc9357SAndroid Build Coastguard Worker }
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker 
655*f6dc9357SAndroid Build Coastguard Worker static UInt32 GetLogSize_Sub(UInt64 size)
656*f6dc9357SAndroid Build Coastguard Worker {
657*f6dc9357SAndroid Build Coastguard Worker   if (size <= 1)
658*f6dc9357SAndroid Build Coastguard Worker     return 0;
659*f6dc9357SAndroid Build Coastguard Worker   const unsigned i = GetLogSize(size) - 1;
660*f6dc9357SAndroid Build Coastguard Worker   UInt32 v;
661*f6dc9357SAndroid Build Coastguard Worker   if (i <= kSubBits)
662*f6dc9357SAndroid Build Coastguard Worker     v = (UInt32)(size) << (kSubBits - i);
663*f6dc9357SAndroid Build Coastguard Worker   else
664*f6dc9357SAndroid Build Coastguard Worker     v = (UInt32)(size >> (i - kSubBits));
665*f6dc9357SAndroid Build Coastguard Worker   return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1));
666*f6dc9357SAndroid Build Coastguard Worker }
667*f6dc9357SAndroid Build Coastguard Worker 
668*f6dc9357SAndroid Build Coastguard Worker 
669*f6dc9357SAndroid Build Coastguard Worker static UInt64 Get_UInt64_from_double(double v)
670*f6dc9357SAndroid Build Coastguard Worker {
671*f6dc9357SAndroid Build Coastguard Worker   const UInt64 kMaxVal = (UInt64)1 << 62;
672*f6dc9357SAndroid Build Coastguard Worker   if (v > (double)(Int64)kMaxVal)
673*f6dc9357SAndroid Build Coastguard Worker     return kMaxVal;
674*f6dc9357SAndroid Build Coastguard Worker   return (UInt64)v;
675*f6dc9357SAndroid Build Coastguard Worker }
676*f6dc9357SAndroid Build Coastguard Worker 
677*f6dc9357SAndroid Build Coastguard Worker static UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d)
678*f6dc9357SAndroid Build Coastguard Worker {
679*f6dc9357SAndroid Build Coastguard Worker   if (d == 0)
680*f6dc9357SAndroid Build Coastguard Worker     d = 1;
681*f6dc9357SAndroid Build Coastguard Worker   const double v =
682*f6dc9357SAndroid Build Coastguard Worker       (double)(Int64)m1 *
683*f6dc9357SAndroid Build Coastguard Worker       (double)(Int64)m2 /
684*f6dc9357SAndroid Build Coastguard Worker       (double)(Int64)d;
685*f6dc9357SAndroid Build Coastguard Worker   return Get_UInt64_from_double(v);
686*f6dc9357SAndroid Build Coastguard Worker   /*
687*f6dc9357SAndroid Build Coastguard Worker   unsigned n1 = GetLogSize(m1);
688*f6dc9357SAndroid Build Coastguard Worker   unsigned n2 = GetLogSize(m2);
689*f6dc9357SAndroid Build Coastguard Worker   while (n1 + n2 > 64)
690*f6dc9357SAndroid Build Coastguard Worker   {
691*f6dc9357SAndroid Build Coastguard Worker     if (n1 >= n2)
692*f6dc9357SAndroid Build Coastguard Worker     {
693*f6dc9357SAndroid Build Coastguard Worker       m1 >>= 1;
694*f6dc9357SAndroid Build Coastguard Worker       n1--;
695*f6dc9357SAndroid Build Coastguard Worker     }
696*f6dc9357SAndroid Build Coastguard Worker     else
697*f6dc9357SAndroid Build Coastguard Worker     {
698*f6dc9357SAndroid Build Coastguard Worker       m2 >>= 1;
699*f6dc9357SAndroid Build Coastguard Worker       n2--;
700*f6dc9357SAndroid Build Coastguard Worker     }
701*f6dc9357SAndroid Build Coastguard Worker     d >>= 1;
702*f6dc9357SAndroid Build Coastguard Worker   }
703*f6dc9357SAndroid Build Coastguard Worker 
704*f6dc9357SAndroid Build Coastguard Worker   if (d == 0)
705*f6dc9357SAndroid Build Coastguard Worker     d = 1;
706*f6dc9357SAndroid Build Coastguard Worker   return m1 * m2 / d;
707*f6dc9357SAndroid Build Coastguard Worker   */
708*f6dc9357SAndroid Build Coastguard Worker }
709*f6dc9357SAndroid Build Coastguard Worker 
710*f6dc9357SAndroid Build Coastguard Worker 
711*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchInfo::GetUsage() const
712*f6dc9357SAndroid Build Coastguard Worker {
713*f6dc9357SAndroid Build Coastguard Worker   UInt64 userTime = UserTime;
714*f6dc9357SAndroid Build Coastguard Worker   UInt64 userFreq = UserFreq;
715*f6dc9357SAndroid Build Coastguard Worker   UInt64 globalTime = GlobalTime;
716*f6dc9357SAndroid Build Coastguard Worker   UInt64 globalFreq = GlobalFreq;
717*f6dc9357SAndroid Build Coastguard Worker 
718*f6dc9357SAndroid Build Coastguard Worker   if (userFreq == 0)
719*f6dc9357SAndroid Build Coastguard Worker     userFreq = 1;
720*f6dc9357SAndroid Build Coastguard Worker   if (globalTime == 0)
721*f6dc9357SAndroid Build Coastguard Worker     globalTime = 1;
722*f6dc9357SAndroid Build Coastguard Worker 
723*f6dc9357SAndroid Build Coastguard Worker   const double v =
724*f6dc9357SAndroid Build Coastguard Worker         ((double)(Int64)userTime / (double)(Int64)userFreq)
725*f6dc9357SAndroid Build Coastguard Worker       * ((double)(Int64)globalFreq / (double)(Int64)globalTime)
726*f6dc9357SAndroid Build Coastguard Worker       * (double)(Int64)kBenchmarkUsageMult;
727*f6dc9357SAndroid Build Coastguard Worker   return Get_UInt64_from_double(v);
728*f6dc9357SAndroid Build Coastguard Worker   /*
729*f6dc9357SAndroid Build Coastguard Worker   return MyMultDiv64(
730*f6dc9357SAndroid Build Coastguard Worker         MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq),
731*f6dc9357SAndroid Build Coastguard Worker         globalFreq, globalTime);
732*f6dc9357SAndroid Build Coastguard Worker   */
733*f6dc9357SAndroid Build Coastguard Worker }
734*f6dc9357SAndroid Build Coastguard Worker 
735*f6dc9357SAndroid Build Coastguard Worker 
736*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
737*f6dc9357SAndroid Build Coastguard Worker {
738*f6dc9357SAndroid Build Coastguard Worker   if (UserTime == 0)
739*f6dc9357SAndroid Build Coastguard Worker   {
740*f6dc9357SAndroid Build Coastguard Worker     return 0;
741*f6dc9357SAndroid Build Coastguard Worker     // userTime = 1;
742*f6dc9357SAndroid Build Coastguard Worker   }
743*f6dc9357SAndroid Build Coastguard Worker   UInt64 globalFreq = GlobalFreq;
744*f6dc9357SAndroid Build Coastguard Worker   if (globalFreq == 0)
745*f6dc9357SAndroid Build Coastguard Worker     globalFreq = 1;
746*f6dc9357SAndroid Build Coastguard Worker 
747*f6dc9357SAndroid Build Coastguard Worker   const double v =
748*f6dc9357SAndroid Build Coastguard Worker         ((double)(Int64)GlobalTime / (double)(Int64)globalFreq)
749*f6dc9357SAndroid Build Coastguard Worker       * ((double)(Int64)UserFreq  / (double)(Int64)UserTime)
750*f6dc9357SAndroid Build Coastguard Worker       * (double)(Int64)rating;
751*f6dc9357SAndroid Build Coastguard Worker   return Get_UInt64_from_double(v);
752*f6dc9357SAndroid Build Coastguard Worker   /*
753*f6dc9357SAndroid Build Coastguard Worker   return MyMultDiv64(
754*f6dc9357SAndroid Build Coastguard Worker         MyMultDiv64(rating, UserFreq, UserTime),
755*f6dc9357SAndroid Build Coastguard Worker         GlobalTime, globalFreq);
756*f6dc9357SAndroid Build Coastguard Worker   */
757*f6dc9357SAndroid Build Coastguard Worker }
758*f6dc9357SAndroid Build Coastguard Worker 
759*f6dc9357SAndroid Build Coastguard Worker 
760*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const
761*f6dc9357SAndroid Build Coastguard Worker {
762*f6dc9357SAndroid Build Coastguard Worker   return MyMultDiv64(numUnits, GlobalFreq, GlobalTime);
763*f6dc9357SAndroid Build Coastguard Worker }
764*f6dc9357SAndroid Build Coastguard Worker 
765*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity)
766*f6dc9357SAndroid Build Coastguard Worker {
767*f6dc9357SAndroid Build Coastguard Worker   return complexity >= 0 ?
768*f6dc9357SAndroid Build Coastguard Worker       size * (UInt32)complexity :
769*f6dc9357SAndroid Build Coastguard Worker       size / (UInt32)(-complexity);
770*f6dc9357SAndroid Build Coastguard Worker }
771*f6dc9357SAndroid Build Coastguard Worker 
772*f6dc9357SAndroid Build Coastguard Worker struct CBenchProps
773*f6dc9357SAndroid Build Coastguard Worker {
774*f6dc9357SAndroid Build Coastguard Worker   bool LzmaRatingMode;
775*f6dc9357SAndroid Build Coastguard Worker 
776*f6dc9357SAndroid Build Coastguard Worker   Int32 EncComplex;
777*f6dc9357SAndroid Build Coastguard Worker   Int32 DecComplexCompr;
778*f6dc9357SAndroid Build Coastguard Worker   Int32 DecComplexUnc;
779*f6dc9357SAndroid Build Coastguard Worker 
780*f6dc9357SAndroid Build Coastguard Worker   unsigned KeySize;
781*f6dc9357SAndroid Build Coastguard Worker 
782*f6dc9357SAndroid Build Coastguard Worker   CBenchProps():
783*f6dc9357SAndroid Build Coastguard Worker       LzmaRatingMode(false),
784*f6dc9357SAndroid Build Coastguard Worker       KeySize(0)
785*f6dc9357SAndroid Build Coastguard Worker     {}
786*f6dc9357SAndroid Build Coastguard Worker 
787*f6dc9357SAndroid Build Coastguard Worker   void SetLzmaCompexity();
788*f6dc9357SAndroid Build Coastguard Worker 
789*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetNumCommands_Enc(UInt64 unpackSize) const
790*f6dc9357SAndroid Build Coastguard Worker   {
791*f6dc9357SAndroid Build Coastguard Worker     const UInt32 kMinSize = 100;
792*f6dc9357SAndroid Build Coastguard Worker     if (unpackSize < kMinSize)
793*f6dc9357SAndroid Build Coastguard Worker       unpackSize = kMinSize;
794*f6dc9357SAndroid Build Coastguard Worker     return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex);
795*f6dc9357SAndroid Build Coastguard Worker   }
796*f6dc9357SAndroid Build Coastguard Worker 
797*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const
798*f6dc9357SAndroid Build Coastguard Worker   {
799*f6dc9357SAndroid Build Coastguard Worker     return
800*f6dc9357SAndroid Build Coastguard Worker         GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) +
801*f6dc9357SAndroid Build Coastguard Worker         GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc);
802*f6dc9357SAndroid Build Coastguard Worker   }
803*f6dc9357SAndroid Build Coastguard Worker 
804*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const;
805*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const;
806*f6dc9357SAndroid Build Coastguard Worker };
807*f6dc9357SAndroid Build Coastguard Worker 
808*f6dc9357SAndroid Build Coastguard Worker void CBenchProps::SetLzmaCompexity()
809*f6dc9357SAndroid Build Coastguard Worker {
810*f6dc9357SAndroid Build Coastguard Worker   EncComplex = 1200;
811*f6dc9357SAndroid Build Coastguard Worker   DecComplexUnc = 4;
812*f6dc9357SAndroid Build Coastguard Worker   DecComplexCompr = 190;
813*f6dc9357SAndroid Build Coastguard Worker   LzmaRatingMode = true;
814*f6dc9357SAndroid Build Coastguard Worker }
815*f6dc9357SAndroid Build Coastguard Worker 
816*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const
817*f6dc9357SAndroid Build Coastguard Worker {
818*f6dc9357SAndroid Build Coastguard Worker   if (dictSize < (1 << kBenchMinDicLogSize))
819*f6dc9357SAndroid Build Coastguard Worker     dictSize = (1 << kBenchMinDicLogSize);
820*f6dc9357SAndroid Build Coastguard Worker   Int32 encComplex = EncComplex;
821*f6dc9357SAndroid Build Coastguard Worker   if (LzmaRatingMode)
822*f6dc9357SAndroid Build Coastguard Worker   {
823*f6dc9357SAndroid Build Coastguard Worker     /*
824*f6dc9357SAndroid Build Coastguard Worker     for (UInt64 uu = 0; uu < (UInt64)0xf << 60;)
825*f6dc9357SAndroid Build Coastguard Worker     {
826*f6dc9357SAndroid Build Coastguard Worker       unsigned rr = GetLogSize_Sub(uu);
827*f6dc9357SAndroid Build Coastguard Worker       printf("\n%16I64x , log = %4x", uu, rr);
828*f6dc9357SAndroid Build Coastguard Worker       uu += 1;
829*f6dc9357SAndroid Build Coastguard Worker       uu += uu / 50;
830*f6dc9357SAndroid Build Coastguard Worker     }
831*f6dc9357SAndroid Build Coastguard Worker     */
832*f6dc9357SAndroid Build Coastguard Worker     // throw 1;
833*f6dc9357SAndroid Build Coastguard Worker     const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits);
834*f6dc9357SAndroid Build Coastguard Worker     encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
835*f6dc9357SAndroid Build Coastguard Worker   }
836*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex);
837*f6dc9357SAndroid Build Coastguard Worker   return MyMultDiv64(numCommands, freq, elapsedTime);
838*f6dc9357SAndroid Build Coastguard Worker }
839*f6dc9357SAndroid Build Coastguard Worker 
840*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const
841*f6dc9357SAndroid Build Coastguard Worker {
842*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations;
843*f6dc9357SAndroid Build Coastguard Worker   return MyMultDiv64(numCommands, freq, elapsedTime);
844*f6dc9357SAndroid Build Coastguard Worker }
845*f6dc9357SAndroid Build Coastguard Worker 
846*f6dc9357SAndroid Build Coastguard Worker 
847*f6dc9357SAndroid Build Coastguard Worker 
848*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const
849*f6dc9357SAndroid Build Coastguard Worker {
850*f6dc9357SAndroid Build Coastguard Worker   CBenchProps props;
851*f6dc9357SAndroid Build Coastguard Worker   props.SetLzmaCompexity();
852*f6dc9357SAndroid Build Coastguard Worker   return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations);
853*f6dc9357SAndroid Build Coastguard Worker }
854*f6dc9357SAndroid Build Coastguard Worker 
855*f6dc9357SAndroid Build Coastguard Worker UInt64 CBenchInfo::GetRating_LzmaDec() const
856*f6dc9357SAndroid Build Coastguard Worker {
857*f6dc9357SAndroid Build Coastguard Worker   CBenchProps props;
858*f6dc9357SAndroid Build Coastguard Worker   props.SetLzmaCompexity();
859*f6dc9357SAndroid Build Coastguard Worker   return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations);
860*f6dc9357SAndroid Build Coastguard Worker }
861*f6dc9357SAndroid Build Coastguard Worker 
862*f6dc9357SAndroid Build Coastguard Worker 
863*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
864*f6dc9357SAndroid Build Coastguard Worker 
865*f6dc9357SAndroid Build Coastguard Worker #define NUM_CPU_LEVELS_MAX 3
866*f6dc9357SAndroid Build Coastguard Worker 
867*f6dc9357SAndroid Build Coastguard Worker struct CAffinityMode
868*f6dc9357SAndroid Build Coastguard Worker {
869*f6dc9357SAndroid Build Coastguard Worker   unsigned NumBundleThreads;
870*f6dc9357SAndroid Build Coastguard Worker   unsigned NumLevels;
871*f6dc9357SAndroid Build Coastguard Worker   unsigned NumCoreThreads;
872*f6dc9357SAndroid Build Coastguard Worker   unsigned NumCores;
873*f6dc9357SAndroid Build Coastguard Worker   // unsigned DivideNum;
874*f6dc9357SAndroid Build Coastguard Worker   UInt32 Sizes[NUM_CPU_LEVELS_MAX];
875*f6dc9357SAndroid Build Coastguard Worker 
876*f6dc9357SAndroid Build Coastguard Worker   void SetLevels(unsigned numCores, unsigned numCoreThreads);
877*f6dc9357SAndroid Build Coastguard Worker   DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const;
878*f6dc9357SAndroid Build Coastguard Worker   bool NeedAffinity() const { return NumBundleThreads != 0; }
879*f6dc9357SAndroid Build Coastguard Worker 
880*f6dc9357SAndroid Build Coastguard Worker   WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const
881*f6dc9357SAndroid Build Coastguard Worker   {
882*f6dc9357SAndroid Build Coastguard Worker     if (NeedAffinity())
883*f6dc9357SAndroid Build Coastguard Worker     {
884*f6dc9357SAndroid Build Coastguard Worker       CCpuSet cpuSet;
885*f6dc9357SAndroid Build Coastguard Worker       GetAffinityMask(bundleIndex, &cpuSet);
886*f6dc9357SAndroid Build Coastguard Worker       return thread.Create_With_CpuSet(startAddress, parameter, &cpuSet);
887*f6dc9357SAndroid Build Coastguard Worker     }
888*f6dc9357SAndroid Build Coastguard Worker     return thread.Create(startAddress, parameter);
889*f6dc9357SAndroid Build Coastguard Worker   }
890*f6dc9357SAndroid Build Coastguard Worker 
891*f6dc9357SAndroid Build Coastguard Worker   CAffinityMode():
892*f6dc9357SAndroid Build Coastguard Worker     NumBundleThreads(0),
893*f6dc9357SAndroid Build Coastguard Worker     NumLevels(0),
894*f6dc9357SAndroid Build Coastguard Worker     NumCoreThreads(1)
895*f6dc9357SAndroid Build Coastguard Worker     // DivideNum(1)
896*f6dc9357SAndroid Build Coastguard Worker     {}
897*f6dc9357SAndroid Build Coastguard Worker };
898*f6dc9357SAndroid Build Coastguard Worker 
899*f6dc9357SAndroid Build Coastguard Worker void CAffinityMode::SetLevels(unsigned numCores, unsigned numCoreThreads)
900*f6dc9357SAndroid Build Coastguard Worker {
901*f6dc9357SAndroid Build Coastguard Worker   NumCores = numCores;
902*f6dc9357SAndroid Build Coastguard Worker   NumCoreThreads = numCoreThreads;
903*f6dc9357SAndroid Build Coastguard Worker   NumLevels = 0;
904*f6dc9357SAndroid Build Coastguard Worker   if (numCoreThreads == 0 || numCores == 0 || numCores % numCoreThreads != 0)
905*f6dc9357SAndroid Build Coastguard Worker     return;
906*f6dc9357SAndroid Build Coastguard Worker   UInt32 c = numCores / numCoreThreads;
907*f6dc9357SAndroid Build Coastguard Worker   UInt32 c2 = 1;
908*f6dc9357SAndroid Build Coastguard Worker   while ((c & 1) == 0)
909*f6dc9357SAndroid Build Coastguard Worker   {
910*f6dc9357SAndroid Build Coastguard Worker     c >>= 1;
911*f6dc9357SAndroid Build Coastguard Worker     c2 <<= 1;
912*f6dc9357SAndroid Build Coastguard Worker   }
913*f6dc9357SAndroid Build Coastguard Worker   if (c2 != 1)
914*f6dc9357SAndroid Build Coastguard Worker     Sizes[NumLevels++] = c2;
915*f6dc9357SAndroid Build Coastguard Worker   if (c != 1)
916*f6dc9357SAndroid Build Coastguard Worker     Sizes[NumLevels++] = c;
917*f6dc9357SAndroid Build Coastguard Worker   if (numCoreThreads != 1)
918*f6dc9357SAndroid Build Coastguard Worker     Sizes[NumLevels++] = numCoreThreads;
919*f6dc9357SAndroid Build Coastguard Worker   if (NumLevels == 0)
920*f6dc9357SAndroid Build Coastguard Worker     Sizes[NumLevels++] = 1;
921*f6dc9357SAndroid Build Coastguard Worker 
922*f6dc9357SAndroid Build Coastguard Worker   /*
923*f6dc9357SAndroid Build Coastguard Worker   printf("\n Cores:");
924*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumLevels; i++)
925*f6dc9357SAndroid Build Coastguard Worker   {
926*f6dc9357SAndroid Build Coastguard Worker     printf(" %d", Sizes[i]);
927*f6dc9357SAndroid Build Coastguard Worker   }
928*f6dc9357SAndroid Build Coastguard Worker   printf("\n");
929*f6dc9357SAndroid Build Coastguard Worker   */
930*f6dc9357SAndroid Build Coastguard Worker }
931*f6dc9357SAndroid Build Coastguard Worker 
932*f6dc9357SAndroid Build Coastguard Worker 
933*f6dc9357SAndroid Build Coastguard Worker DWORD_PTR CAffinityMode::GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const
934*f6dc9357SAndroid Build Coastguard Worker {
935*f6dc9357SAndroid Build Coastguard Worker   CpuSet_Zero(cpuSet);
936*f6dc9357SAndroid Build Coastguard Worker 
937*f6dc9357SAndroid Build Coastguard Worker   if (NumLevels == 0)
938*f6dc9357SAndroid Build Coastguard Worker     return 0;
939*f6dc9357SAndroid Build Coastguard Worker 
940*f6dc9357SAndroid Build Coastguard Worker   // printf("\n%2d", bundleIndex);
941*f6dc9357SAndroid Build Coastguard Worker 
942*f6dc9357SAndroid Build Coastguard Worker   /*
943*f6dc9357SAndroid Build Coastguard Worker   UInt32 low = 0;
944*f6dc9357SAndroid Build Coastguard Worker   if (DivideNum != 1)
945*f6dc9357SAndroid Build Coastguard Worker   {
946*f6dc9357SAndroid Build Coastguard Worker     low = bundleIndex % DivideNum;
947*f6dc9357SAndroid Build Coastguard Worker     bundleIndex /= DivideNum;
948*f6dc9357SAndroid Build Coastguard Worker   }
949*f6dc9357SAndroid Build Coastguard Worker   */
950*f6dc9357SAndroid Build Coastguard Worker 
951*f6dc9357SAndroid Build Coastguard Worker   UInt32 numGroups = NumCores / NumBundleThreads;
952*f6dc9357SAndroid Build Coastguard Worker   UInt32 m = bundleIndex % numGroups;
953*f6dc9357SAndroid Build Coastguard Worker   UInt32 v = 0;
954*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumLevels; i++)
955*f6dc9357SAndroid Build Coastguard Worker   {
956*f6dc9357SAndroid Build Coastguard Worker     UInt32 size = Sizes[i];
957*f6dc9357SAndroid Build Coastguard Worker     while ((size & 1) == 0)
958*f6dc9357SAndroid Build Coastguard Worker     {
959*f6dc9357SAndroid Build Coastguard Worker       v *= 2;
960*f6dc9357SAndroid Build Coastguard Worker       v |= (m & 1);
961*f6dc9357SAndroid Build Coastguard Worker       m >>= 1;
962*f6dc9357SAndroid Build Coastguard Worker       size >>= 1;
963*f6dc9357SAndroid Build Coastguard Worker     }
964*f6dc9357SAndroid Build Coastguard Worker     v *= size;
965*f6dc9357SAndroid Build Coastguard Worker     v += m % size;
966*f6dc9357SAndroid Build Coastguard Worker     m /= size;
967*f6dc9357SAndroid Build Coastguard Worker   }
968*f6dc9357SAndroid Build Coastguard Worker 
969*f6dc9357SAndroid Build Coastguard Worker   // UInt32 nb = NumBundleThreads / DivideNum;
970*f6dc9357SAndroid Build Coastguard Worker   UInt32 nb = NumBundleThreads;
971*f6dc9357SAndroid Build Coastguard Worker 
972*f6dc9357SAndroid Build Coastguard Worker   DWORD_PTR mask = ((DWORD_PTR)1 << nb) - 1;
973*f6dc9357SAndroid Build Coastguard Worker   // v += low;
974*f6dc9357SAndroid Build Coastguard Worker   mask <<= v;
975*f6dc9357SAndroid Build Coastguard Worker 
976*f6dc9357SAndroid Build Coastguard Worker   // printf(" %2d %8x \n ", v, (unsigned)mask);
977*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
978*f6dc9357SAndroid Build Coastguard Worker     *cpuSet = mask;
979*f6dc9357SAndroid Build Coastguard Worker   #else
980*f6dc9357SAndroid Build Coastguard Worker   {
981*f6dc9357SAndroid Build Coastguard Worker     for (unsigned k = 0; k < nb; k++)
982*f6dc9357SAndroid Build Coastguard Worker       CpuSet_Set(cpuSet, v + k);
983*f6dc9357SAndroid Build Coastguard Worker   }
984*f6dc9357SAndroid Build Coastguard Worker   #endif
985*f6dc9357SAndroid Build Coastguard Worker 
986*f6dc9357SAndroid Build Coastguard Worker   return mask;
987*f6dc9357SAndroid Build Coastguard Worker }
988*f6dc9357SAndroid Build Coastguard Worker 
989*f6dc9357SAndroid Build Coastguard Worker 
990*f6dc9357SAndroid Build Coastguard Worker struct CBenchSyncCommon
991*f6dc9357SAndroid Build Coastguard Worker {
992*f6dc9357SAndroid Build Coastguard Worker   bool ExitMode;
993*f6dc9357SAndroid Build Coastguard Worker   NSynchronization::CManualResetEvent StartEvent;
994*f6dc9357SAndroid Build Coastguard Worker 
995*f6dc9357SAndroid Build Coastguard Worker   CBenchSyncCommon(): ExitMode(false) {}
996*f6dc9357SAndroid Build Coastguard Worker };
997*f6dc9357SAndroid Build Coastguard Worker 
998*f6dc9357SAndroid Build Coastguard Worker #endif
999*f6dc9357SAndroid Build Coastguard Worker 
1000*f6dc9357SAndroid Build Coastguard Worker 
1001*f6dc9357SAndroid Build Coastguard Worker 
1002*f6dc9357SAndroid Build Coastguard Worker enum E_CheckCrcMode
1003*f6dc9357SAndroid Build Coastguard Worker {
1004*f6dc9357SAndroid Build Coastguard Worker   k_CheckCrcMode_Never = 0,
1005*f6dc9357SAndroid Build Coastguard Worker   k_CheckCrcMode_Always = 1,
1006*f6dc9357SAndroid Build Coastguard Worker   k_CheckCrcMode_FirstPass = 2
1007*f6dc9357SAndroid Build Coastguard Worker };
1008*f6dc9357SAndroid Build Coastguard Worker 
1009*f6dc9357SAndroid Build Coastguard Worker class CEncoderInfo;
1010*f6dc9357SAndroid Build Coastguard Worker 
1011*f6dc9357SAndroid Build Coastguard Worker class CEncoderInfo Z7_final
1012*f6dc9357SAndroid Build Coastguard Worker {
1013*f6dc9357SAndroid Build Coastguard Worker   Z7_CLASS_NO_COPY(CEncoderInfo)
1014*f6dc9357SAndroid Build Coastguard Worker 
1015*f6dc9357SAndroid Build Coastguard Worker public:
1016*f6dc9357SAndroid Build Coastguard Worker 
1017*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1018*f6dc9357SAndroid Build Coastguard Worker   NWindows::CThread thread[2];
1019*f6dc9357SAndroid Build Coastguard Worker   NSynchronization::CManualResetEvent ReadyEvent;
1020*f6dc9357SAndroid Build Coastguard Worker   UInt32 NumDecoderSubThreads;
1021*f6dc9357SAndroid Build Coastguard Worker   CBenchSyncCommon *Common;
1022*f6dc9357SAndroid Build Coastguard Worker   UInt32 EncoderIndex;
1023*f6dc9357SAndroid Build Coastguard Worker   UInt32 NumEncoderInternalThreads;
1024*f6dc9357SAndroid Build Coastguard Worker   CAffinityMode AffinityMode;
1025*f6dc9357SAndroid Build Coastguard Worker   bool IsGlobalMtMode; // if more than one benchmark encoder threads
1026*f6dc9357SAndroid Build Coastguard Worker   #endif
1027*f6dc9357SAndroid Build Coastguard Worker 
1028*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressCoder> _encoder;
1029*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressFilter> _encoderFilter;
1030*f6dc9357SAndroid Build Coastguard Worker   CBenchProgressInfo *progressInfoSpec[2];
1031*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressProgressInfo> progressInfo[2];
1032*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumIterations;
1033*f6dc9357SAndroid Build Coastguard Worker 
1034*f6dc9357SAndroid Build Coastguard Worker   UInt32 Salt;
1035*f6dc9357SAndroid Build Coastguard Worker 
1036*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_ALLOCA
1037*f6dc9357SAndroid Build Coastguard Worker   size_t AllocaSize;
1038*f6dc9357SAndroid Build Coastguard Worker   #endif
1039*f6dc9357SAndroid Build Coastguard Worker 
1040*f6dc9357SAndroid Build Coastguard Worker   unsigned KeySize;
1041*f6dc9357SAndroid Build Coastguard Worker   Byte _key[32];
1042*f6dc9357SAndroid Build Coastguard Worker   Byte _iv[16];
1043*f6dc9357SAndroid Build Coastguard Worker 
1044*f6dc9357SAndroid Build Coastguard Worker   HRESULT Set_Key_and_IV(ICryptoProperties *cp)
1045*f6dc9357SAndroid Build Coastguard Worker   {
1046*f6dc9357SAndroid Build Coastguard Worker     RINOK(cp->SetKey(_key, KeySize))
1047*f6dc9357SAndroid Build Coastguard Worker     return cp->SetInitVector(_iv, sizeof(_iv));
1048*f6dc9357SAndroid Build Coastguard Worker   }
1049*f6dc9357SAndroid Build Coastguard Worker 
1050*f6dc9357SAndroid Build Coastguard Worker   Byte _psw[16];
1051*f6dc9357SAndroid Build Coastguard Worker 
1052*f6dc9357SAndroid Build Coastguard Worker   bool CheckCrc_Enc;    /* = 1, if we want to check packed data crcs after each pass
1053*f6dc9357SAndroid Build Coastguard Worker                                 used for filter and usual coders */
1054*f6dc9357SAndroid Build Coastguard Worker   bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass
1055*f6dc9357SAndroid Build Coastguard Worker                                 used only for filter */
1056*f6dc9357SAndroid Build Coastguard Worker   E_CheckCrcMode CheckCrcMode_Dec;
1057*f6dc9357SAndroid Build Coastguard Worker 
1058*f6dc9357SAndroid Build Coastguard Worker   struct CDecoderInfo
1059*f6dc9357SAndroid Build Coastguard Worker   {
1060*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo *Encoder;
1061*f6dc9357SAndroid Build Coastguard Worker     UInt32 DecoderIndex;
1062*f6dc9357SAndroid Build Coastguard Worker     bool CallbackMode;
1063*f6dc9357SAndroid Build Coastguard Worker 
1064*f6dc9357SAndroid Build Coastguard Worker     #ifdef USE_ALLOCA
1065*f6dc9357SAndroid Build Coastguard Worker     size_t AllocaSize;
1066*f6dc9357SAndroid Build Coastguard Worker     #endif
1067*f6dc9357SAndroid Build Coastguard Worker   };
1068*f6dc9357SAndroid Build Coastguard Worker   CDecoderInfo decodersInfo[2];
1069*f6dc9357SAndroid Build Coastguard Worker 
1070*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressCoder> _decoders[2];
1071*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressFilter> _decoderFilter;
1072*f6dc9357SAndroid Build Coastguard Worker 
1073*f6dc9357SAndroid Build Coastguard Worker   HRESULT Results[2];
1074*f6dc9357SAndroid Build Coastguard Worker   CBenchmarkOutStream *outStreamSpec;
1075*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> outStream;
1076*f6dc9357SAndroid Build Coastguard Worker   IBenchCallback *callback;
1077*f6dc9357SAndroid Build Coastguard Worker   IBenchPrintCallback *printCallback;
1078*f6dc9357SAndroid Build Coastguard Worker   UInt32 crc;
1079*f6dc9357SAndroid Build Coastguard Worker   size_t kBufferSize;
1080*f6dc9357SAndroid Build Coastguard Worker   size_t compressedSize;
1081*f6dc9357SAndroid Build Coastguard Worker   const Byte *uncompressedDataPtr;
1082*f6dc9357SAndroid Build Coastguard Worker 
1083*f6dc9357SAndroid Build Coastguard Worker   const Byte *fileData;
1084*f6dc9357SAndroid Build Coastguard Worker   CBenchRandomGenerator rg;
1085*f6dc9357SAndroid Build Coastguard Worker 
1086*f6dc9357SAndroid Build Coastguard Worker   CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!!
1087*f6dc9357SAndroid Build Coastguard Worker 
1088*f6dc9357SAndroid Build Coastguard Worker   // CBenchmarkOutStream *propStreamSpec;
1089*f6dc9357SAndroid Build Coastguard Worker   Byte propsData[kMaxMethodPropSize];
1090*f6dc9357SAndroid Build Coastguard Worker   CBufPtrSeqOutStream *propStreamSpec;
1091*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> propStream;
1092*f6dc9357SAndroid Build Coastguard Worker 
1093*f6dc9357SAndroid Build Coastguard Worker   unsigned generateDictBits;
1094*f6dc9357SAndroid Build Coastguard Worker   COneMethodInfo _method;
1095*f6dc9357SAndroid Build Coastguard Worker 
1096*f6dc9357SAndroid Build Coastguard Worker   // for decode
1097*f6dc9357SAndroid Build Coastguard Worker   size_t _uncompressedDataSize;
1098*f6dc9357SAndroid Build Coastguard Worker 
1099*f6dc9357SAndroid Build Coastguard Worker   HRESULT Generate();
1100*f6dc9357SAndroid Build Coastguard Worker   HRESULT Encode();
1101*f6dc9357SAndroid Build Coastguard Worker   HRESULT Decode(UInt32 decoderIndex);
1102*f6dc9357SAndroid Build Coastguard Worker 
1103*f6dc9357SAndroid Build Coastguard Worker   CEncoderInfo():
1104*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1105*f6dc9357SAndroid Build Coastguard Worker     Common(NULL),
1106*f6dc9357SAndroid Build Coastguard Worker     IsGlobalMtMode(true),
1107*f6dc9357SAndroid Build Coastguard Worker     #endif
1108*f6dc9357SAndroid Build Coastguard Worker     Salt(0),
1109*f6dc9357SAndroid Build Coastguard Worker     KeySize(0),
1110*f6dc9357SAndroid Build Coastguard Worker     CheckCrc_Enc(true),
1111*f6dc9357SAndroid Build Coastguard Worker     UseRealData_Enc(true),
1112*f6dc9357SAndroid Build Coastguard Worker     CheckCrcMode_Dec(k_CheckCrcMode_Always),
1113*f6dc9357SAndroid Build Coastguard Worker     outStreamSpec(NULL),
1114*f6dc9357SAndroid Build Coastguard Worker     callback(NULL),
1115*f6dc9357SAndroid Build Coastguard Worker     printCallback(NULL),
1116*f6dc9357SAndroid Build Coastguard Worker     fileData(NULL),
1117*f6dc9357SAndroid Build Coastguard Worker     propStreamSpec(NULL)
1118*f6dc9357SAndroid Build Coastguard Worker     {}
1119*f6dc9357SAndroid Build Coastguard Worker 
1120*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1121*f6dc9357SAndroid Build Coastguard Worker 
1122*f6dc9357SAndroid Build Coastguard Worker   static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
1123*f6dc9357SAndroid Build Coastguard Worker   {
1124*f6dc9357SAndroid Build Coastguard Worker     HRESULT res;
1125*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo *encoder = (CEncoderInfo *)param;
1126*f6dc9357SAndroid Build Coastguard Worker     try
1127*f6dc9357SAndroid Build Coastguard Worker     {
1128*f6dc9357SAndroid Build Coastguard Worker       #ifdef USE_ALLOCA
1129*f6dc9357SAndroid Build Coastguard Worker       alloca(encoder->AllocaSize);
1130*f6dc9357SAndroid Build Coastguard Worker       #endif
1131*f6dc9357SAndroid Build Coastguard Worker 
1132*f6dc9357SAndroid Build Coastguard Worker       res = encoder->Encode();
1133*f6dc9357SAndroid Build Coastguard Worker     }
1134*f6dc9357SAndroid Build Coastguard Worker     catch(...)
1135*f6dc9357SAndroid Build Coastguard Worker     {
1136*f6dc9357SAndroid Build Coastguard Worker       res = E_FAIL;
1137*f6dc9357SAndroid Build Coastguard Worker     }
1138*f6dc9357SAndroid Build Coastguard Worker     encoder->Results[0] = res;
1139*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
1140*f6dc9357SAndroid Build Coastguard Worker       encoder->progressInfoSpec[0]->Status->SetResult(res);
1141*f6dc9357SAndroid Build Coastguard Worker     encoder->ReadyEvent.Set();
1142*f6dc9357SAndroid Build Coastguard Worker     return THREAD_FUNC_RET_ZERO;
1143*f6dc9357SAndroid Build Coastguard Worker   }
1144*f6dc9357SAndroid Build Coastguard Worker 
1145*f6dc9357SAndroid Build Coastguard Worker   static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
1146*f6dc9357SAndroid Build Coastguard Worker   {
1147*f6dc9357SAndroid Build Coastguard Worker     CDecoderInfo *decoder = (CDecoderInfo *)param;
1148*f6dc9357SAndroid Build Coastguard Worker 
1149*f6dc9357SAndroid Build Coastguard Worker     #ifdef USE_ALLOCA
1150*f6dc9357SAndroid Build Coastguard Worker     alloca(decoder->AllocaSize);
1151*f6dc9357SAndroid Build Coastguard Worker     // printf("\nalloca=%d\n", (unsigned)decoder->AllocaSize);
1152*f6dc9357SAndroid Build Coastguard Worker     #endif
1153*f6dc9357SAndroid Build Coastguard Worker 
1154*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo *encoder = decoder->Encoder;
1155*f6dc9357SAndroid Build Coastguard Worker     encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
1156*f6dc9357SAndroid Build Coastguard Worker     return THREAD_FUNC_RET_ZERO;
1157*f6dc9357SAndroid Build Coastguard Worker   }
1158*f6dc9357SAndroid Build Coastguard Worker 
1159*f6dc9357SAndroid Build Coastguard Worker   HRESULT CreateEncoderThread()
1160*f6dc9357SAndroid Build Coastguard Worker   {
1161*f6dc9357SAndroid Build Coastguard Worker     WRes res = 0;
1162*f6dc9357SAndroid Build Coastguard Worker     if (!ReadyEvent.IsCreated())
1163*f6dc9357SAndroid Build Coastguard Worker       res = ReadyEvent.Create();
1164*f6dc9357SAndroid Build Coastguard Worker     if (res == 0)
1165*f6dc9357SAndroid Build Coastguard Worker       res = AffinityMode.CreateThread_WithAffinity(thread[0], EncodeThreadFunction, this,
1166*f6dc9357SAndroid Build Coastguard Worker           EncoderIndex);
1167*f6dc9357SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(res);
1168*f6dc9357SAndroid Build Coastguard Worker   }
1169*f6dc9357SAndroid Build Coastguard Worker 
1170*f6dc9357SAndroid Build Coastguard Worker   HRESULT CreateDecoderThread(unsigned index, bool callbackMode
1171*f6dc9357SAndroid Build Coastguard Worker       #ifdef USE_ALLOCA
1172*f6dc9357SAndroid Build Coastguard Worker       , size_t allocaSize
1173*f6dc9357SAndroid Build Coastguard Worker       #endif
1174*f6dc9357SAndroid Build Coastguard Worker       )
1175*f6dc9357SAndroid Build Coastguard Worker   {
1176*f6dc9357SAndroid Build Coastguard Worker     CDecoderInfo &decoder = decodersInfo[index];
1177*f6dc9357SAndroid Build Coastguard Worker     decoder.DecoderIndex = index;
1178*f6dc9357SAndroid Build Coastguard Worker     decoder.Encoder = this;
1179*f6dc9357SAndroid Build Coastguard Worker 
1180*f6dc9357SAndroid Build Coastguard Worker     #ifdef USE_ALLOCA
1181*f6dc9357SAndroid Build Coastguard Worker     decoder.AllocaSize = allocaSize;
1182*f6dc9357SAndroid Build Coastguard Worker     #endif
1183*f6dc9357SAndroid Build Coastguard Worker 
1184*f6dc9357SAndroid Build Coastguard Worker     decoder.CallbackMode = callbackMode;
1185*f6dc9357SAndroid Build Coastguard Worker 
1186*f6dc9357SAndroid Build Coastguard Worker     WRes res = AffinityMode.CreateThread_WithAffinity(thread[index], DecodeThreadFunction, &decoder,
1187*f6dc9357SAndroid Build Coastguard Worker         // EncoderIndex * NumEncoderInternalThreads + index
1188*f6dc9357SAndroid Build Coastguard Worker         EncoderIndex
1189*f6dc9357SAndroid Build Coastguard Worker         );
1190*f6dc9357SAndroid Build Coastguard Worker 
1191*f6dc9357SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(res);
1192*f6dc9357SAndroid Build Coastguard Worker   }
1193*f6dc9357SAndroid Build Coastguard Worker 
1194*f6dc9357SAndroid Build Coastguard Worker   #endif
1195*f6dc9357SAndroid Build Coastguard Worker };
1196*f6dc9357SAndroid Build Coastguard Worker 
1197*f6dc9357SAndroid Build Coastguard Worker 
1198*f6dc9357SAndroid Build Coastguard Worker 
1199*f6dc9357SAndroid Build Coastguard Worker 
1200*f6dc9357SAndroid Build Coastguard Worker static size_t GetBenchCompressedSize(size_t bufferSize)
1201*f6dc9357SAndroid Build Coastguard Worker {
1202*f6dc9357SAndroid Build Coastguard Worker   return kCompressedAdditionalSize + bufferSize + bufferSize / 16;
1203*f6dc9357SAndroid Build Coastguard Worker   // kBufferSize / 2;
1204*f6dc9357SAndroid Build Coastguard Worker }
1205*f6dc9357SAndroid Build Coastguard Worker 
1206*f6dc9357SAndroid Build Coastguard Worker 
1207*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoderInfo::Generate()
1208*f6dc9357SAndroid Build Coastguard Worker {
1209*f6dc9357SAndroid Build Coastguard Worker   const COneMethodInfo &method = _method;
1210*f6dc9357SAndroid Build Coastguard Worker 
1211*f6dc9357SAndroid Build Coastguard Worker   // we need extra space, if input data is already compressed
1212*f6dc9357SAndroid Build Coastguard Worker   const size_t kCompressedBufferSize = _encoderFilter ?
1213*f6dc9357SAndroid Build Coastguard Worker       kBufferSize :
1214*f6dc9357SAndroid Build Coastguard Worker       GetBenchCompressedSize(kBufferSize);
1215*f6dc9357SAndroid Build Coastguard Worker 
1216*f6dc9357SAndroid Build Coastguard Worker   if (kCompressedBufferSize < kBufferSize)
1217*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
1218*f6dc9357SAndroid Build Coastguard Worker 
1219*f6dc9357SAndroid Build Coastguard Worker   uncompressedDataPtr = fileData;
1220*f6dc9357SAndroid Build Coastguard Worker   if (fileData)
1221*f6dc9357SAndroid Build Coastguard Worker   {
1222*f6dc9357SAndroid Build Coastguard Worker     #if !defined(Z7_ST)
1223*f6dc9357SAndroid Build Coastguard Worker     if (IsGlobalMtMode)
1224*f6dc9357SAndroid Build Coastguard Worker     {
1225*f6dc9357SAndroid Build Coastguard Worker       /* we copy the data to local buffer of thread to eliminate
1226*f6dc9357SAndroid Build Coastguard Worker          using of shared buffer by different threads */
1227*f6dc9357SAndroid Build Coastguard Worker       ALLOC_WITH_HRESULT(&rg, kBufferSize)
1228*f6dc9357SAndroid Build Coastguard Worker       memcpy((Byte *)rg, fileData, kBufferSize);
1229*f6dc9357SAndroid Build Coastguard Worker       uncompressedDataPtr = (const Byte *)rg;
1230*f6dc9357SAndroid Build Coastguard Worker     }
1231*f6dc9357SAndroid Build Coastguard Worker     #endif
1232*f6dc9357SAndroid Build Coastguard Worker   }
1233*f6dc9357SAndroid Build Coastguard Worker   else
1234*f6dc9357SAndroid Build Coastguard Worker   {
1235*f6dc9357SAndroid Build Coastguard Worker     ALLOC_WITH_HRESULT(&rg, kBufferSize)
1236*f6dc9357SAndroid Build Coastguard Worker     // DWORD ttt = GetTickCount();
1237*f6dc9357SAndroid Build Coastguard Worker     if (generateDictBits == 0)
1238*f6dc9357SAndroid Build Coastguard Worker       rg.GenerateSimpleRandom(Salt);
1239*f6dc9357SAndroid Build Coastguard Worker     else
1240*f6dc9357SAndroid Build Coastguard Worker     {
1241*f6dc9357SAndroid Build Coastguard Worker       if (generateDictBits >= sizeof(size_t) * 8
1242*f6dc9357SAndroid Build Coastguard Worker           && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1)))
1243*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
1244*f6dc9357SAndroid Build Coastguard Worker       rg.GenerateLz(generateDictBits, Salt);
1245*f6dc9357SAndroid Build Coastguard Worker       // return E_ABORT; // for debug
1246*f6dc9357SAndroid Build Coastguard Worker     }
1247*f6dc9357SAndroid Build Coastguard Worker     // printf("\n%d\n            ", GetTickCount() - ttt);
1248*f6dc9357SAndroid Build Coastguard Worker 
1249*f6dc9357SAndroid Build Coastguard Worker     crc = CrcCalc((const Byte *)rg, rg.Size());
1250*f6dc9357SAndroid Build Coastguard Worker     uncompressedDataPtr = (const Byte *)rg;
1251*f6dc9357SAndroid Build Coastguard Worker   }
1252*f6dc9357SAndroid Build Coastguard Worker 
1253*f6dc9357SAndroid Build Coastguard Worker   if (!outStream)
1254*f6dc9357SAndroid Build Coastguard Worker   {
1255*f6dc9357SAndroid Build Coastguard Worker     outStreamSpec = new CBenchmarkOutStream;
1256*f6dc9357SAndroid Build Coastguard Worker     outStream = outStreamSpec;
1257*f6dc9357SAndroid Build Coastguard Worker   }
1258*f6dc9357SAndroid Build Coastguard Worker 
1259*f6dc9357SAndroid Build Coastguard Worker   ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize)
1260*f6dc9357SAndroid Build Coastguard Worker 
1261*f6dc9357SAndroid Build Coastguard Worker   if (_encoderFilter)
1262*f6dc9357SAndroid Build Coastguard Worker   {
1263*f6dc9357SAndroid Build Coastguard Worker     /* we try to reduce the number of memcpy() in main encoding loop.
1264*f6dc9357SAndroid Build Coastguard Worker        so we copy data to temp buffers here */
1265*f6dc9357SAndroid Build Coastguard Worker     ALLOC_WITH_HRESULT(&rgCopy, kBufferSize)
1266*f6dc9357SAndroid Build Coastguard Worker     memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize);
1267*f6dc9357SAndroid Build Coastguard Worker     memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize);
1268*f6dc9357SAndroid Build Coastguard Worker   }
1269*f6dc9357SAndroid Build Coastguard Worker 
1270*f6dc9357SAndroid Build Coastguard Worker   if (!propStream)
1271*f6dc9357SAndroid Build Coastguard Worker   {
1272*f6dc9357SAndroid Build Coastguard Worker     propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream;
1273*f6dc9357SAndroid Build Coastguard Worker     propStream = propStreamSpec;
1274*f6dc9357SAndroid Build Coastguard Worker   }
1275*f6dc9357SAndroid Build Coastguard Worker   // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize);
1276*f6dc9357SAndroid Build Coastguard Worker   // propStreamSpec->Init(true, false);
1277*f6dc9357SAndroid Build Coastguard Worker   propStreamSpec->Init(propsData, sizeof(propsData));
1278*f6dc9357SAndroid Build Coastguard Worker 
1279*f6dc9357SAndroid Build Coastguard Worker 
1280*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IUnknown> coder;
1281*f6dc9357SAndroid Build Coastguard Worker   if (_encoderFilter)
1282*f6dc9357SAndroid Build Coastguard Worker     coder = _encoderFilter;
1283*f6dc9357SAndroid Build Coastguard Worker   else
1284*f6dc9357SAndroid Build Coastguard Worker     coder = _encoder;
1285*f6dc9357SAndroid Build Coastguard Worker   {
1286*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressSetCoderProperties> scp;
1287*f6dc9357SAndroid Build Coastguard Worker     coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
1288*f6dc9357SAndroid Build Coastguard Worker     if (scp)
1289*f6dc9357SAndroid Build Coastguard Worker     {
1290*f6dc9357SAndroid Build Coastguard Worker       const UInt64 reduceSize = kBufferSize;
1291*f6dc9357SAndroid Build Coastguard Worker 
1292*f6dc9357SAndroid Build Coastguard Worker       /* in posix new thread uses same affinity as parent thread,
1293*f6dc9357SAndroid Build Coastguard Worker          so we don't need to send affinity to coder in posix */
1294*f6dc9357SAndroid Build Coastguard Worker       UInt64 affMask;
1295*f6dc9357SAndroid Build Coastguard Worker       #if !defined(Z7_ST) && defined(_WIN32)
1296*f6dc9357SAndroid Build Coastguard Worker       {
1297*f6dc9357SAndroid Build Coastguard Worker         CCpuSet cpuSet;
1298*f6dc9357SAndroid Build Coastguard Worker         affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet);
1299*f6dc9357SAndroid Build Coastguard Worker       }
1300*f6dc9357SAndroid Build Coastguard Worker       #else
1301*f6dc9357SAndroid Build Coastguard Worker         affMask = 0;
1302*f6dc9357SAndroid Build Coastguard Worker       #endif
1303*f6dc9357SAndroid Build Coastguard Worker       // affMask <<= 3; // debug line: to test no affinity in coder;
1304*f6dc9357SAndroid Build Coastguard Worker       // affMask = 0;
1305*f6dc9357SAndroid Build Coastguard Worker 
1306*f6dc9357SAndroid Build Coastguard Worker       RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, (affMask != 0 ? &affMask : NULL)))
1307*f6dc9357SAndroid Build Coastguard Worker     }
1308*f6dc9357SAndroid Build Coastguard Worker     else
1309*f6dc9357SAndroid Build Coastguard Worker     {
1310*f6dc9357SAndroid Build Coastguard Worker       if (method.AreThereNonOptionalProps())
1311*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
1312*f6dc9357SAndroid Build Coastguard Worker     }
1313*f6dc9357SAndroid Build Coastguard Worker 
1314*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressWriteCoderProperties> writeCoderProps;
1315*f6dc9357SAndroid Build Coastguard Worker     coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
1316*f6dc9357SAndroid Build Coastguard Worker     if (writeCoderProps)
1317*f6dc9357SAndroid Build Coastguard Worker     {
1318*f6dc9357SAndroid Build Coastguard Worker       RINOK(writeCoderProps->WriteCoderProperties(propStream))
1319*f6dc9357SAndroid Build Coastguard Worker     }
1320*f6dc9357SAndroid Build Coastguard Worker 
1321*f6dc9357SAndroid Build Coastguard Worker     {
1322*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ICryptoSetPassword> sp;
1323*f6dc9357SAndroid Build Coastguard Worker       coder.QueryInterface(IID_ICryptoSetPassword, &sp);
1324*f6dc9357SAndroid Build Coastguard Worker       if (sp)
1325*f6dc9357SAndroid Build Coastguard Worker       {
1326*f6dc9357SAndroid Build Coastguard Worker         RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
1327*f6dc9357SAndroid Build Coastguard Worker 
1328*f6dc9357SAndroid Build Coastguard Worker         // we must call encoding one time to calculate password key for key cache.
1329*f6dc9357SAndroid Build Coastguard Worker         // it must be after WriteCoderProperties!
1330*f6dc9357SAndroid Build Coastguard Worker         Byte temp[16];
1331*f6dc9357SAndroid Build Coastguard Worker         memset(temp, 0, sizeof(temp));
1332*f6dc9357SAndroid Build Coastguard Worker 
1333*f6dc9357SAndroid Build Coastguard Worker         if (_encoderFilter)
1334*f6dc9357SAndroid Build Coastguard Worker         {
1335*f6dc9357SAndroid Build Coastguard Worker           _encoderFilter->Init();
1336*f6dc9357SAndroid Build Coastguard Worker           _encoderFilter->Filter(temp, sizeof(temp));
1337*f6dc9357SAndroid Build Coastguard Worker         }
1338*f6dc9357SAndroid Build Coastguard Worker         else
1339*f6dc9357SAndroid Build Coastguard Worker         {
1340*f6dc9357SAndroid Build Coastguard Worker           CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1341*f6dc9357SAndroid Build Coastguard Worker           CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1342*f6dc9357SAndroid Build Coastguard Worker           inStreamSpec->Init(temp, sizeof(temp));
1343*f6dc9357SAndroid Build Coastguard Worker 
1344*f6dc9357SAndroid Build Coastguard Worker           CCrcOutStream *crcStreamSpec = new CCrcOutStream;
1345*f6dc9357SAndroid Build Coastguard Worker           CMyComPtr<ISequentialOutStream> crcStream = crcStreamSpec;
1346*f6dc9357SAndroid Build Coastguard Worker           crcStreamSpec->Init();
1347*f6dc9357SAndroid Build Coastguard Worker 
1348*f6dc9357SAndroid Build Coastguard Worker           RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL))
1349*f6dc9357SAndroid Build Coastguard Worker         }
1350*f6dc9357SAndroid Build Coastguard Worker       }
1351*f6dc9357SAndroid Build Coastguard Worker     }
1352*f6dc9357SAndroid Build Coastguard Worker   }
1353*f6dc9357SAndroid Build Coastguard Worker 
1354*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1355*f6dc9357SAndroid Build Coastguard Worker }
1356*f6dc9357SAndroid Build Coastguard Worker 
1357*f6dc9357SAndroid Build Coastguard Worker 
1358*f6dc9357SAndroid Build Coastguard Worker static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc)
1359*f6dc9357SAndroid Build Coastguard Worker {
1360*f6dc9357SAndroid Build Coastguard Worker   while (size != 0)
1361*f6dc9357SAndroid Build Coastguard Worker   {
1362*f6dc9357SAndroid Build Coastguard Worker     UInt32 cur = crc ? 1 << 17 : 1 << 24;
1363*f6dc9357SAndroid Build Coastguard Worker     if (cur > size)
1364*f6dc9357SAndroid Build Coastguard Worker       cur = (UInt32)size;
1365*f6dc9357SAndroid Build Coastguard Worker     UInt32 processed = filter->Filter(data, cur);
1366*f6dc9357SAndroid Build Coastguard Worker     /* if (processed > size) (in AES filter), we must fill last block with zeros.
1367*f6dc9357SAndroid Build Coastguard Worker        but it is not important for benchmark. So we just copy that data without filtering.
1368*f6dc9357SAndroid Build Coastguard Worker        if (processed == 0) then filter can't process more  */
1369*f6dc9357SAndroid Build Coastguard Worker     if (processed > size || processed == 0)
1370*f6dc9357SAndroid Build Coastguard Worker       processed = (UInt32)size;
1371*f6dc9357SAndroid Build Coastguard Worker     if (crc)
1372*f6dc9357SAndroid Build Coastguard Worker       *crc = CrcUpdate(*crc, data, processed);
1373*f6dc9357SAndroid Build Coastguard Worker     data += processed;
1374*f6dc9357SAndroid Build Coastguard Worker     size -= processed;
1375*f6dc9357SAndroid Build Coastguard Worker   }
1376*f6dc9357SAndroid Build Coastguard Worker }
1377*f6dc9357SAndroid Build Coastguard Worker 
1378*f6dc9357SAndroid Build Coastguard Worker 
1379*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoderInfo::Encode()
1380*f6dc9357SAndroid Build Coastguard Worker {
1381*f6dc9357SAndroid Build Coastguard Worker   // printf("\nCEncoderInfo::Generate\n");
1382*f6dc9357SAndroid Build Coastguard Worker 
1383*f6dc9357SAndroid Build Coastguard Worker   RINOK(Generate())
1384*f6dc9357SAndroid Build Coastguard Worker 
1385*f6dc9357SAndroid Build Coastguard Worker   // printf("\n2222\n");
1386*f6dc9357SAndroid Build Coastguard Worker 
1387*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1388*f6dc9357SAndroid Build Coastguard Worker   if (Common)
1389*f6dc9357SAndroid Build Coastguard Worker   {
1390*f6dc9357SAndroid Build Coastguard Worker     Results[0] = S_OK;
1391*f6dc9357SAndroid Build Coastguard Worker     WRes wres = ReadyEvent.Set();
1392*f6dc9357SAndroid Build Coastguard Worker     if (wres == 0)
1393*f6dc9357SAndroid Build Coastguard Worker       wres = Common->StartEvent.Lock();
1394*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
1395*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
1396*f6dc9357SAndroid Build Coastguard Worker     if (Common->ExitMode)
1397*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1398*f6dc9357SAndroid Build Coastguard Worker   }
1399*f6dc9357SAndroid Build Coastguard Worker   else
1400*f6dc9357SAndroid Build Coastguard Worker   #endif
1401*f6dc9357SAndroid Build Coastguard Worker   {
1402*f6dc9357SAndroid Build Coastguard Worker     CBenchProgressInfo *bpi = progressInfoSpec[0];
1403*f6dc9357SAndroid Build Coastguard Worker     bpi->SetStartTime();
1404*f6dc9357SAndroid Build Coastguard Worker   }
1405*f6dc9357SAndroid Build Coastguard Worker 
1406*f6dc9357SAndroid Build Coastguard Worker 
1407*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
1408*f6dc9357SAndroid Build Coastguard Worker   bi.UnpackSize = 0;
1409*f6dc9357SAndroid Build Coastguard Worker   bi.PackSize = 0;
1410*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICryptoProperties> cp;
1411*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IUnknown> coder;
1412*f6dc9357SAndroid Build Coastguard Worker   if (_encoderFilter)
1413*f6dc9357SAndroid Build Coastguard Worker     coder = _encoderFilter;
1414*f6dc9357SAndroid Build Coastguard Worker   else
1415*f6dc9357SAndroid Build Coastguard Worker     coder = _encoder;
1416*f6dc9357SAndroid Build Coastguard Worker   coder.QueryInterface(IID_ICryptoProperties, &cp);
1417*f6dc9357SAndroid Build Coastguard Worker   CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1418*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1419*f6dc9357SAndroid Build Coastguard Worker 
1420*f6dc9357SAndroid Build Coastguard Worker   if (cp)
1421*f6dc9357SAndroid Build Coastguard Worker   {
1422*f6dc9357SAndroid Build Coastguard Worker     RINOK(Set_Key_and_IV(cp))
1423*f6dc9357SAndroid Build Coastguard Worker   }
1424*f6dc9357SAndroid Build Coastguard Worker 
1425*f6dc9357SAndroid Build Coastguard Worker   compressedSize = 0;
1426*f6dc9357SAndroid Build Coastguard Worker   if (_encoderFilter)
1427*f6dc9357SAndroid Build Coastguard Worker     compressedSize = kBufferSize;
1428*f6dc9357SAndroid Build Coastguard Worker 
1429*f6dc9357SAndroid Build Coastguard Worker   // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec;
1430*f6dc9357SAndroid Build Coastguard Worker   UInt64 prev = 0;
1431*f6dc9357SAndroid Build Coastguard Worker 
1432*f6dc9357SAndroid Build Coastguard Worker   const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF);
1433*f6dc9357SAndroid Build Coastguard Worker   const bool useCrc = (mask < NumIterations);
1434*f6dc9357SAndroid Build Coastguard Worker   bool crcPrev_defined = false;
1435*f6dc9357SAndroid Build Coastguard Worker   UInt32 crcPrev = 0;
1436*f6dc9357SAndroid Build Coastguard Worker 
1437*f6dc9357SAndroid Build Coastguard Worker   bool useRealData_Enc = UseRealData_Enc;
1438*f6dc9357SAndroid Build Coastguard Worker   bool data_Was_Changed = false;
1439*f6dc9357SAndroid Build Coastguard Worker   if (useRealData_Enc)
1440*f6dc9357SAndroid Build Coastguard Worker   {
1441*f6dc9357SAndroid Build Coastguard Worker     /* we want memcpy() for each iteration including first iteration.
1442*f6dc9357SAndroid Build Coastguard Worker        So results will be equal for different number of iterations */
1443*f6dc9357SAndroid Build Coastguard Worker     data_Was_Changed = true;
1444*f6dc9357SAndroid Build Coastguard Worker   }
1445*f6dc9357SAndroid Build Coastguard Worker 
1446*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numIterations = NumIterations;
1447*f6dc9357SAndroid Build Coastguard Worker   UInt64 i = numIterations;
1448*f6dc9357SAndroid Build Coastguard Worker     // printCallback->NewLine();
1449*f6dc9357SAndroid Build Coastguard Worker 
1450*f6dc9357SAndroid Build Coastguard Worker   while (i != 0)
1451*f6dc9357SAndroid Build Coastguard Worker   {
1452*f6dc9357SAndroid Build Coastguard Worker     i--;
1453*f6dc9357SAndroid Build Coastguard Worker     if (printCallback && bi.UnpackSize - prev >= (1 << 26))
1454*f6dc9357SAndroid Build Coastguard Worker     {
1455*f6dc9357SAndroid Build Coastguard Worker       prev = bi.UnpackSize;
1456*f6dc9357SAndroid Build Coastguard Worker       RINOK(printCallback->CheckBreak())
1457*f6dc9357SAndroid Build Coastguard Worker     }
1458*f6dc9357SAndroid Build Coastguard Worker 
1459*f6dc9357SAndroid Build Coastguard Worker     /*
1460*f6dc9357SAndroid Build Coastguard Worker     CBenchInfo info;
1461*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec[0]->SetStartTime();
1462*f6dc9357SAndroid Build Coastguard Worker     */
1463*f6dc9357SAndroid Build Coastguard Worker 
1464*f6dc9357SAndroid Build Coastguard Worker     bool calcCrc = false;
1465*f6dc9357SAndroid Build Coastguard Worker     if (useCrc)
1466*f6dc9357SAndroid Build Coastguard Worker       calcCrc = (((UInt32)i & mask) == 0);
1467*f6dc9357SAndroid Build Coastguard Worker 
1468*f6dc9357SAndroid Build Coastguard Worker     if (_encoderFilter)
1469*f6dc9357SAndroid Build Coastguard Worker     {
1470*f6dc9357SAndroid Build Coastguard Worker       Byte *filterData = rgCopy;
1471*f6dc9357SAndroid Build Coastguard Worker       if (i == numIterations - 1 || calcCrc || useRealData_Enc)
1472*f6dc9357SAndroid Build Coastguard Worker       {
1473*f6dc9357SAndroid Build Coastguard Worker         // printf("\nfilterData = (Byte *)*outStreamSpec;\n");
1474*f6dc9357SAndroid Build Coastguard Worker         filterData = (Byte *)*outStreamSpec;
1475*f6dc9357SAndroid Build Coastguard Worker         if (data_Was_Changed)
1476*f6dc9357SAndroid Build Coastguard Worker         {
1477*f6dc9357SAndroid Build Coastguard Worker           // printf("\nmemcpy(filterData, uncompressedDataPtr\n");
1478*f6dc9357SAndroid Build Coastguard Worker           memcpy(filterData, uncompressedDataPtr, kBufferSize);
1479*f6dc9357SAndroid Build Coastguard Worker         }
1480*f6dc9357SAndroid Build Coastguard Worker         data_Was_Changed = true;
1481*f6dc9357SAndroid Build Coastguard Worker       }
1482*f6dc9357SAndroid Build Coastguard Worker       _encoderFilter->Init();
1483*f6dc9357SAndroid Build Coastguard Worker       if (calcCrc)
1484*f6dc9357SAndroid Build Coastguard Worker       {
1485*f6dc9357SAndroid Build Coastguard Worker         // printf("\nInitCrc\n");
1486*f6dc9357SAndroid Build Coastguard Worker         outStreamSpec->InitCrc();
1487*f6dc9357SAndroid Build Coastguard Worker       }
1488*f6dc9357SAndroid Build Coastguard Worker       // printf("\nMy_FilterBench\n");
1489*f6dc9357SAndroid Build Coastguard Worker       My_FilterBench(_encoderFilter, filterData, kBufferSize,
1490*f6dc9357SAndroid Build Coastguard Worker           calcCrc ? &outStreamSpec->Crc : NULL);
1491*f6dc9357SAndroid Build Coastguard Worker     }
1492*f6dc9357SAndroid Build Coastguard Worker     else
1493*f6dc9357SAndroid Build Coastguard Worker     {
1494*f6dc9357SAndroid Build Coastguard Worker       outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations
1495*f6dc9357SAndroid Build Coastguard Worker       inStreamSpec->Init(uncompressedDataPtr, kBufferSize);
1496*f6dc9357SAndroid Build Coastguard Worker       RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]))
1497*f6dc9357SAndroid Build Coastguard Worker       if (!inStreamSpec->WasFinished())
1498*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
1499*f6dc9357SAndroid Build Coastguard Worker       if (compressedSize != outStreamSpec->Pos)
1500*f6dc9357SAndroid Build Coastguard Worker       {
1501*f6dc9357SAndroid Build Coastguard Worker         if (compressedSize != 0)
1502*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL;
1503*f6dc9357SAndroid Build Coastguard Worker         compressedSize = outStreamSpec->Pos;
1504*f6dc9357SAndroid Build Coastguard Worker       }
1505*f6dc9357SAndroid Build Coastguard Worker     }
1506*f6dc9357SAndroid Build Coastguard Worker 
1507*f6dc9357SAndroid Build Coastguard Worker     // outStreamSpec->Print();
1508*f6dc9357SAndroid Build Coastguard Worker 
1509*f6dc9357SAndroid Build Coastguard Worker     if (calcCrc)
1510*f6dc9357SAndroid Build Coastguard Worker     {
1511*f6dc9357SAndroid Build Coastguard Worker       const UInt32 crc2 = CRC_GET_DIGEST(outStreamSpec->Crc);
1512*f6dc9357SAndroid Build Coastguard Worker       if (crcPrev_defined && crcPrev != crc2)
1513*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
1514*f6dc9357SAndroid Build Coastguard Worker       crcPrev = crc2;
1515*f6dc9357SAndroid Build Coastguard Worker       crcPrev_defined = true;
1516*f6dc9357SAndroid Build Coastguard Worker     }
1517*f6dc9357SAndroid Build Coastguard Worker 
1518*f6dc9357SAndroid Build Coastguard Worker     bi.UnpackSize += kBufferSize;
1519*f6dc9357SAndroid Build Coastguard Worker     bi.PackSize += compressedSize;
1520*f6dc9357SAndroid Build Coastguard Worker 
1521*f6dc9357SAndroid Build Coastguard Worker     /*
1522*f6dc9357SAndroid Build Coastguard Worker     {
1523*f6dc9357SAndroid Build Coastguard Worker       progressInfoSpec[0]->SetFinishTime(info);
1524*f6dc9357SAndroid Build Coastguard Worker       info.UnpackSize = 0;
1525*f6dc9357SAndroid Build Coastguard Worker       info.PackSize = 0;
1526*f6dc9357SAndroid Build Coastguard Worker       info.NumIterations = 1;
1527*f6dc9357SAndroid Build Coastguard Worker 
1528*f6dc9357SAndroid Build Coastguard Worker       info.UnpackSize = kBufferSize;
1529*f6dc9357SAndroid Build Coastguard Worker       info.PackSize = compressedSize;
1530*f6dc9357SAndroid Build Coastguard Worker       // printf("\n%7d\n", encoder.compressedSize);
1531*f6dc9357SAndroid Build Coastguard Worker 
1532*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->SetEncodeResult(info, true))
1533*f6dc9357SAndroid Build Coastguard Worker       printCallback->NewLine();
1534*f6dc9357SAndroid Build Coastguard Worker     }
1535*f6dc9357SAndroid Build Coastguard Worker     */
1536*f6dc9357SAndroid Build Coastguard Worker 
1537*f6dc9357SAndroid Build Coastguard Worker   }
1538*f6dc9357SAndroid Build Coastguard Worker 
1539*f6dc9357SAndroid Build Coastguard Worker   _encoder.Release();
1540*f6dc9357SAndroid Build Coastguard Worker   _encoderFilter.Release();
1541*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1542*f6dc9357SAndroid Build Coastguard Worker }
1543*f6dc9357SAndroid Build Coastguard Worker 
1544*f6dc9357SAndroid Build Coastguard Worker 
1545*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
1546*f6dc9357SAndroid Build Coastguard Worker {
1547*f6dc9357SAndroid Build Coastguard Worker   CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1548*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1549*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressCoder> &decoder = _decoders[decoderIndex];
1550*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IUnknown> coder;
1551*f6dc9357SAndroid Build Coastguard Worker   if (_decoderFilter)
1552*f6dc9357SAndroid Build Coastguard Worker   {
1553*f6dc9357SAndroid Build Coastguard Worker     if (decoderIndex != 0)
1554*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
1555*f6dc9357SAndroid Build Coastguard Worker     coder = _decoderFilter;
1556*f6dc9357SAndroid Build Coastguard Worker   }
1557*f6dc9357SAndroid Build Coastguard Worker   else
1558*f6dc9357SAndroid Build Coastguard Worker     coder = decoder;
1559*f6dc9357SAndroid Build Coastguard Worker 
1560*f6dc9357SAndroid Build Coastguard Worker   // printf("\ndecoderIndex = %d, stack = %p", decoderIndex, &coder);
1561*f6dc9357SAndroid Build Coastguard Worker 
1562*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
1563*f6dc9357SAndroid Build Coastguard Worker   coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
1564*f6dc9357SAndroid Build Coastguard Worker   if (!setDecProps && propStreamSpec->GetPos() != 0)
1565*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
1566*f6dc9357SAndroid Build Coastguard Worker 
1567*f6dc9357SAndroid Build Coastguard Worker   CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
1568*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
1569*f6dc9357SAndroid Build Coastguard Worker 
1570*f6dc9357SAndroid Build Coastguard Worker   CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
1571*f6dc9357SAndroid Build Coastguard Worker   pi->BenchInfo.UnpackSize = 0;
1572*f6dc9357SAndroid Build Coastguard Worker   pi->BenchInfo.PackSize = 0;
1573*f6dc9357SAndroid Build Coastguard Worker 
1574*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1575*f6dc9357SAndroid Build Coastguard Worker   {
1576*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressSetCoderMt> setCoderMt;
1577*f6dc9357SAndroid Build Coastguard Worker     coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
1578*f6dc9357SAndroid Build Coastguard Worker     if (setCoderMt)
1579*f6dc9357SAndroid Build Coastguard Worker     {
1580*f6dc9357SAndroid Build Coastguard Worker       RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads))
1581*f6dc9357SAndroid Build Coastguard Worker     }
1582*f6dc9357SAndroid Build Coastguard Worker   }
1583*f6dc9357SAndroid Build Coastguard Worker   #endif
1584*f6dc9357SAndroid Build Coastguard Worker 
1585*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressSetCoderProperties> scp;
1586*f6dc9357SAndroid Build Coastguard Worker   coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
1587*f6dc9357SAndroid Build Coastguard Worker   if (scp)
1588*f6dc9357SAndroid Build Coastguard Worker   {
1589*f6dc9357SAndroid Build Coastguard Worker     const UInt64 reduceSize = _uncompressedDataSize;
1590*f6dc9357SAndroid Build Coastguard Worker     RINOK(_method.SetCoderProps(scp, &reduceSize))
1591*f6dc9357SAndroid Build Coastguard Worker   }
1592*f6dc9357SAndroid Build Coastguard Worker 
1593*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICryptoProperties> cp;
1594*f6dc9357SAndroid Build Coastguard Worker   coder.QueryInterface(IID_ICryptoProperties, &cp);
1595*f6dc9357SAndroid Build Coastguard Worker 
1596*f6dc9357SAndroid Build Coastguard Worker   if (setDecProps)
1597*f6dc9357SAndroid Build Coastguard Worker   {
1598*f6dc9357SAndroid Build Coastguard Worker     RINOK(setDecProps->SetDecoderProperties2(
1599*f6dc9357SAndroid Build Coastguard Worker         /* (const Byte *)*propStreamSpec, */
1600*f6dc9357SAndroid Build Coastguard Worker         propsData,
1601*f6dc9357SAndroid Build Coastguard Worker         (UInt32)propStreamSpec->GetPos()))
1602*f6dc9357SAndroid Build Coastguard Worker   }
1603*f6dc9357SAndroid Build Coastguard Worker 
1604*f6dc9357SAndroid Build Coastguard Worker   {
1605*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICryptoSetPassword> sp;
1606*f6dc9357SAndroid Build Coastguard Worker     coder.QueryInterface(IID_ICryptoSetPassword, &sp);
1607*f6dc9357SAndroid Build Coastguard Worker     if (sp)
1608*f6dc9357SAndroid Build Coastguard Worker     {
1609*f6dc9357SAndroid Build Coastguard Worker       RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)))
1610*f6dc9357SAndroid Build Coastguard Worker     }
1611*f6dc9357SAndroid Build Coastguard Worker   }
1612*f6dc9357SAndroid Build Coastguard Worker 
1613*f6dc9357SAndroid Build Coastguard Worker   UInt64 prev = 0;
1614*f6dc9357SAndroid Build Coastguard Worker 
1615*f6dc9357SAndroid Build Coastguard Worker   if (cp)
1616*f6dc9357SAndroid Build Coastguard Worker   {
1617*f6dc9357SAndroid Build Coastguard Worker     RINOK(Set_Key_and_IV(cp))
1618*f6dc9357SAndroid Build Coastguard Worker   }
1619*f6dc9357SAndroid Build Coastguard Worker 
1620*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressSetFinishMode> setFinishMode;
1621*f6dc9357SAndroid Build Coastguard Worker 
1622*f6dc9357SAndroid Build Coastguard Worker   if (_decoderFilter)
1623*f6dc9357SAndroid Build Coastguard Worker   {
1624*f6dc9357SAndroid Build Coastguard Worker     if (compressedSize > rgCopy.Size())
1625*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
1626*f6dc9357SAndroid Build Coastguard Worker   }
1627*f6dc9357SAndroid Build Coastguard Worker   else
1628*f6dc9357SAndroid Build Coastguard Worker   {
1629*f6dc9357SAndroid Build Coastguard Worker     decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
1630*f6dc9357SAndroid Build Coastguard Worker   }
1631*f6dc9357SAndroid Build Coastguard Worker 
1632*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numIterations = NumIterations;
1633*f6dc9357SAndroid Build Coastguard Worker   const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec;
1634*f6dc9357SAndroid Build Coastguard Worker 
1635*f6dc9357SAndroid Build Coastguard Worker   for (UInt64 i = 0; i < numIterations; i++)
1636*f6dc9357SAndroid Build Coastguard Worker   {
1637*f6dc9357SAndroid Build Coastguard Worker     if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26))
1638*f6dc9357SAndroid Build Coastguard Worker     {
1639*f6dc9357SAndroid Build Coastguard Worker       RINOK(printCallback->CheckBreak())
1640*f6dc9357SAndroid Build Coastguard Worker       prev = pi->BenchInfo.UnpackSize;
1641*f6dc9357SAndroid Build Coastguard Worker     }
1642*f6dc9357SAndroid Build Coastguard Worker 
1643*f6dc9357SAndroid Build Coastguard Worker     const UInt64 outSize = kBufferSize;
1644*f6dc9357SAndroid Build Coastguard Worker     bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never);
1645*f6dc9357SAndroid Build Coastguard Worker 
1646*f6dc9357SAndroid Build Coastguard Worker     crcOutStreamSpec->Init();
1647*f6dc9357SAndroid Build Coastguard Worker 
1648*f6dc9357SAndroid Build Coastguard Worker     if (_decoderFilter)
1649*f6dc9357SAndroid Build Coastguard Worker     {
1650*f6dc9357SAndroid Build Coastguard Worker       Byte *filterData = (Byte *)*outStreamSpec;
1651*f6dc9357SAndroid Build Coastguard Worker       if (calcCrc)
1652*f6dc9357SAndroid Build Coastguard Worker       {
1653*f6dc9357SAndroid Build Coastguard Worker         calcCrc = (i == 0);
1654*f6dc9357SAndroid Build Coastguard Worker         if (checkCrcMode == k_CheckCrcMode_Always)
1655*f6dc9357SAndroid Build Coastguard Worker         {
1656*f6dc9357SAndroid Build Coastguard Worker           calcCrc = true;
1657*f6dc9357SAndroid Build Coastguard Worker           memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize);
1658*f6dc9357SAndroid Build Coastguard Worker           filterData = rgCopy;
1659*f6dc9357SAndroid Build Coastguard Worker         }
1660*f6dc9357SAndroid Build Coastguard Worker       }
1661*f6dc9357SAndroid Build Coastguard Worker       _decoderFilter->Init();
1662*f6dc9357SAndroid Build Coastguard Worker       My_FilterBench(_decoderFilter, filterData, compressedSize,
1663*f6dc9357SAndroid Build Coastguard Worker           calcCrc ? &crcOutStreamSpec->Crc : NULL);
1664*f6dc9357SAndroid Build Coastguard Worker     }
1665*f6dc9357SAndroid Build Coastguard Worker     else
1666*f6dc9357SAndroid Build Coastguard Worker     {
1667*f6dc9357SAndroid Build Coastguard Worker       crcOutStreamSpec->CalcCrc = calcCrc;
1668*f6dc9357SAndroid Build Coastguard Worker       inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize);
1669*f6dc9357SAndroid Build Coastguard Worker 
1670*f6dc9357SAndroid Build Coastguard Worker       if (setFinishMode)
1671*f6dc9357SAndroid Build Coastguard Worker       {
1672*f6dc9357SAndroid Build Coastguard Worker         RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)))
1673*f6dc9357SAndroid Build Coastguard Worker       }
1674*f6dc9357SAndroid Build Coastguard Worker 
1675*f6dc9357SAndroid Build Coastguard Worker       RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex]))
1676*f6dc9357SAndroid Build Coastguard Worker 
1677*f6dc9357SAndroid Build Coastguard Worker       if (setFinishMode)
1678*f6dc9357SAndroid Build Coastguard Worker       {
1679*f6dc9357SAndroid Build Coastguard Worker         if (!inStreamSpec->WasFinished())
1680*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
1681*f6dc9357SAndroid Build Coastguard Worker 
1682*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
1683*f6dc9357SAndroid Build Coastguard Worker         decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
1684*f6dc9357SAndroid Build Coastguard Worker 
1685*f6dc9357SAndroid Build Coastguard Worker         if (getInStreamProcessedSize)
1686*f6dc9357SAndroid Build Coastguard Worker         {
1687*f6dc9357SAndroid Build Coastguard Worker           UInt64 processed;
1688*f6dc9357SAndroid Build Coastguard Worker           RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
1689*f6dc9357SAndroid Build Coastguard Worker           if (processed != compressedSize)
1690*f6dc9357SAndroid Build Coastguard Worker             return S_FALSE;
1691*f6dc9357SAndroid Build Coastguard Worker         }
1692*f6dc9357SAndroid Build Coastguard Worker       }
1693*f6dc9357SAndroid Build Coastguard Worker 
1694*f6dc9357SAndroid Build Coastguard Worker       if (crcOutStreamSpec->Pos != outSize)
1695*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
1696*f6dc9357SAndroid Build Coastguard Worker     }
1697*f6dc9357SAndroid Build Coastguard Worker 
1698*f6dc9357SAndroid Build Coastguard Worker     if (calcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
1699*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
1700*f6dc9357SAndroid Build Coastguard Worker 
1701*f6dc9357SAndroid Build Coastguard Worker     pi->BenchInfo.UnpackSize += kBufferSize;
1702*f6dc9357SAndroid Build Coastguard Worker     pi->BenchInfo.PackSize += compressedSize;
1703*f6dc9357SAndroid Build Coastguard Worker   }
1704*f6dc9357SAndroid Build Coastguard Worker 
1705*f6dc9357SAndroid Build Coastguard Worker   decoder.Release();
1706*f6dc9357SAndroid Build Coastguard Worker   _decoderFilter.Release();
1707*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1708*f6dc9357SAndroid Build Coastguard Worker }
1709*f6dc9357SAndroid Build Coastguard Worker 
1710*f6dc9357SAndroid Build Coastguard Worker 
1711*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kNumThreadsMax = (1 << 12);
1712*f6dc9357SAndroid Build Coastguard Worker 
1713*f6dc9357SAndroid Build Coastguard Worker struct CBenchEncoders
1714*f6dc9357SAndroid Build Coastguard Worker {
1715*f6dc9357SAndroid Build Coastguard Worker   CEncoderInfo *encoders;
1716*f6dc9357SAndroid Build Coastguard Worker   CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
1717*f6dc9357SAndroid Build Coastguard Worker   ~CBenchEncoders() { delete []encoders; }
1718*f6dc9357SAndroid Build Coastguard Worker };
1719*f6dc9357SAndroid Build Coastguard Worker 
1720*f6dc9357SAndroid Build Coastguard Worker 
1721*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
1722*f6dc9357SAndroid Build Coastguard Worker {
1723*f6dc9357SAndroid Build Coastguard Worker   if (numCommands < (1 << 4))
1724*f6dc9357SAndroid Build Coastguard Worker     numCommands = (1 << 4);
1725*f6dc9357SAndroid Build Coastguard Worker   UInt64 res = complexInCommands / numCommands;
1726*f6dc9357SAndroid Build Coastguard Worker   return (res == 0 ? 1 : res);
1727*f6dc9357SAndroid Build Coastguard Worker }
1728*f6dc9357SAndroid Build Coastguard Worker 
1729*f6dc9357SAndroid Build Coastguard Worker 
1730*f6dc9357SAndroid Build Coastguard Worker 
1731*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1732*f6dc9357SAndroid Build Coastguard Worker 
1733*f6dc9357SAndroid Build Coastguard Worker // ---------- CBenchThreadsFlusher ----------
1734*f6dc9357SAndroid Build Coastguard Worker 
1735*f6dc9357SAndroid Build Coastguard Worker struct CBenchThreadsFlusher
1736*f6dc9357SAndroid Build Coastguard Worker {
1737*f6dc9357SAndroid Build Coastguard Worker   CBenchEncoders *EncodersSpec;
1738*f6dc9357SAndroid Build Coastguard Worker   CBenchSyncCommon Common;
1739*f6dc9357SAndroid Build Coastguard Worker   unsigned NumThreads;
1740*f6dc9357SAndroid Build Coastguard Worker   bool NeedClose;
1741*f6dc9357SAndroid Build Coastguard Worker 
1742*f6dc9357SAndroid Build Coastguard Worker   CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {}
1743*f6dc9357SAndroid Build Coastguard Worker 
1744*f6dc9357SAndroid Build Coastguard Worker   ~CBenchThreadsFlusher()
1745*f6dc9357SAndroid Build Coastguard Worker   {
1746*f6dc9357SAndroid Build Coastguard Worker     StartAndWait(true);
1747*f6dc9357SAndroid Build Coastguard Worker   }
1748*f6dc9357SAndroid Build Coastguard Worker 
1749*f6dc9357SAndroid Build Coastguard Worker   WRes StartAndWait(bool exitMode = false);
1750*f6dc9357SAndroid Build Coastguard Worker };
1751*f6dc9357SAndroid Build Coastguard Worker 
1752*f6dc9357SAndroid Build Coastguard Worker 
1753*f6dc9357SAndroid Build Coastguard Worker WRes CBenchThreadsFlusher::StartAndWait(bool exitMode)
1754*f6dc9357SAndroid Build Coastguard Worker {
1755*f6dc9357SAndroid Build Coastguard Worker   if (!NeedClose)
1756*f6dc9357SAndroid Build Coastguard Worker     return 0;
1757*f6dc9357SAndroid Build Coastguard Worker 
1758*f6dc9357SAndroid Build Coastguard Worker   Common.ExitMode = exitMode;
1759*f6dc9357SAndroid Build Coastguard Worker   WRes res = Common.StartEvent.Set();
1760*f6dc9357SAndroid Build Coastguard Worker 
1761*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumThreads; i++)
1762*f6dc9357SAndroid Build Coastguard Worker   {
1763*f6dc9357SAndroid Build Coastguard Worker     NWindows::CThread &t = EncodersSpec->encoders[i].thread[0];
1764*f6dc9357SAndroid Build Coastguard Worker     if (t.IsCreated())
1765*f6dc9357SAndroid Build Coastguard Worker     {
1766*f6dc9357SAndroid Build Coastguard Worker       WRes res2 = t.Wait_Close();
1767*f6dc9357SAndroid Build Coastguard Worker       if (res == 0)
1768*f6dc9357SAndroid Build Coastguard Worker         res = res2;
1769*f6dc9357SAndroid Build Coastguard Worker     }
1770*f6dc9357SAndroid Build Coastguard Worker   }
1771*f6dc9357SAndroid Build Coastguard Worker   NeedClose = false;
1772*f6dc9357SAndroid Build Coastguard Worker   return res;
1773*f6dc9357SAndroid Build Coastguard Worker }
1774*f6dc9357SAndroid Build Coastguard Worker 
1775*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_ST
1776*f6dc9357SAndroid Build Coastguard Worker 
1777*f6dc9357SAndroid Build Coastguard Worker 
1778*f6dc9357SAndroid Build Coastguard Worker 
1779*f6dc9357SAndroid Build Coastguard Worker static void SetPseudoRand(Byte *data, size_t size, UInt32 startValue)
1780*f6dc9357SAndroid Build Coastguard Worker {
1781*f6dc9357SAndroid Build Coastguard Worker   for (size_t i = 0; i < size; i++)
1782*f6dc9357SAndroid Build Coastguard Worker   {
1783*f6dc9357SAndroid Build Coastguard Worker     data[i] = (Byte)startValue;
1784*f6dc9357SAndroid Build Coastguard Worker     startValue++;
1785*f6dc9357SAndroid Build Coastguard Worker   }
1786*f6dc9357SAndroid Build Coastguard Worker }
1787*f6dc9357SAndroid Build Coastguard Worker 
1788*f6dc9357SAndroid Build Coastguard Worker 
1789*f6dc9357SAndroid Build Coastguard Worker 
1790*f6dc9357SAndroid Build Coastguard Worker static HRESULT MethodBench(
1791*f6dc9357SAndroid Build Coastguard Worker     DECL_EXTERNAL_CODECS_LOC_VARS
1792*f6dc9357SAndroid Build Coastguard Worker     UInt64 complexInCommands,
1793*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1794*f6dc9357SAndroid Build Coastguard Worker       bool oldLzmaBenchMode,
1795*f6dc9357SAndroid Build Coastguard Worker       UInt32 numThreads,
1796*f6dc9357SAndroid Build Coastguard Worker       const CAffinityMode *affinityMode,
1797*f6dc9357SAndroid Build Coastguard Worker     #endif
1798*f6dc9357SAndroid Build Coastguard Worker     const COneMethodInfo &method2,
1799*f6dc9357SAndroid Build Coastguard Worker     size_t uncompressedDataSize,
1800*f6dc9357SAndroid Build Coastguard Worker     const Byte *fileData,
1801*f6dc9357SAndroid Build Coastguard Worker     unsigned generateDictBits,
1802*f6dc9357SAndroid Build Coastguard Worker 
1803*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *printCallback,
1804*f6dc9357SAndroid Build Coastguard Worker     IBenchCallback *callback,
1805*f6dc9357SAndroid Build Coastguard Worker     CBenchProps *benchProps)
1806*f6dc9357SAndroid Build Coastguard Worker {
1807*f6dc9357SAndroid Build Coastguard Worker   COneMethodInfo method = method2;
1808*f6dc9357SAndroid Build Coastguard Worker   UInt64 methodId;
1809*f6dc9357SAndroid Build Coastguard Worker   UInt32 numStreams;
1810*f6dc9357SAndroid Build Coastguard Worker   bool isFilter;
1811*f6dc9357SAndroid Build Coastguard Worker   const int codecIndex = FindMethod_Index(
1812*f6dc9357SAndroid Build Coastguard Worker       EXTERNAL_CODECS_LOC_VARS
1813*f6dc9357SAndroid Build Coastguard Worker       method.MethodName, true,
1814*f6dc9357SAndroid Build Coastguard Worker       methodId, numStreams, isFilter);
1815*f6dc9357SAndroid Build Coastguard Worker   if (codecIndex < 0)
1816*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
1817*f6dc9357SAndroid Build Coastguard Worker   if (numStreams != 1)
1818*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
1819*f6dc9357SAndroid Build Coastguard Worker 
1820*f6dc9357SAndroid Build Coastguard Worker   UInt32 numEncoderThreads = 1;
1821*f6dc9357SAndroid Build Coastguard Worker   UInt32 numSubDecoderThreads = 1;
1822*f6dc9357SAndroid Build Coastguard Worker 
1823*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1824*f6dc9357SAndroid Build Coastguard Worker     numEncoderThreads = numThreads;
1825*f6dc9357SAndroid Build Coastguard Worker 
1826*f6dc9357SAndroid Build Coastguard Worker     if (oldLzmaBenchMode)
1827*f6dc9357SAndroid Build Coastguard Worker     if (methodId == k_LZMA)
1828*f6dc9357SAndroid Build Coastguard Worker     {
1829*f6dc9357SAndroid Build Coastguard Worker       if (numThreads == 1 && method.Get_NumThreads() < 0)
1830*f6dc9357SAndroid Build Coastguard Worker         method.AddProp_NumThreads(1);
1831*f6dc9357SAndroid Build Coastguard Worker       const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads();
1832*f6dc9357SAndroid Build Coastguard Worker       if (numThreads > 1 && numLzmaThreads > 1)
1833*f6dc9357SAndroid Build Coastguard Worker       {
1834*f6dc9357SAndroid Build Coastguard Worker         numEncoderThreads = (numThreads + 1) / 2; // 20.03
1835*f6dc9357SAndroid Build Coastguard Worker         numSubDecoderThreads = 2;
1836*f6dc9357SAndroid Build Coastguard Worker       }
1837*f6dc9357SAndroid Build Coastguard Worker     }
1838*f6dc9357SAndroid Build Coastguard Worker 
1839*f6dc9357SAndroid Build Coastguard Worker   const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity();
1840*f6dc9357SAndroid Build Coastguard Worker 
1841*f6dc9357SAndroid Build Coastguard Worker   #endif
1842*f6dc9357SAndroid Build Coastguard Worker 
1843*f6dc9357SAndroid Build Coastguard Worker   CBenchEncoders encodersSpec(numEncoderThreads);
1844*f6dc9357SAndroid Build Coastguard Worker   CEncoderInfo *encoders = encodersSpec.encoders;
1845*f6dc9357SAndroid Build Coastguard Worker 
1846*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
1847*f6dc9357SAndroid Build Coastguard Worker 
1848*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
1849*f6dc9357SAndroid Build Coastguard Worker   {
1850*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo &encoder = encoders[i];
1851*f6dc9357SAndroid Build Coastguard Worker     encoder.callback = (i == 0) ? callback : NULL;
1852*f6dc9357SAndroid Build Coastguard Worker     encoder.printCallback = printCallback;
1853*f6dc9357SAndroid Build Coastguard Worker 
1854*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1855*f6dc9357SAndroid Build Coastguard Worker     encoder.EncoderIndex = i;
1856*f6dc9357SAndroid Build Coastguard Worker     encoder.NumEncoderInternalThreads = numSubDecoderThreads;
1857*f6dc9357SAndroid Build Coastguard Worker     encoder.AffinityMode = *affinityMode;
1858*f6dc9357SAndroid Build Coastguard Worker 
1859*f6dc9357SAndroid Build Coastguard Worker     /*
1860*f6dc9357SAndroid Build Coastguard Worker     if (numSubDecoderThreads > 1)
1861*f6dc9357SAndroid Build Coastguard Worker     if (encoder.AffinityMode.NeedAffinity()
1862*f6dc9357SAndroid Build Coastguard Worker         && encoder.AffinityMode.NumBundleThreads == 1)
1863*f6dc9357SAndroid Build Coastguard Worker     {
1864*f6dc9357SAndroid Build Coastguard Worker       // if old LZMA benchmark uses two threads in coder, we increase (NumBundleThreads) for old LZMA benchmark uses two threads instead of one
1865*f6dc9357SAndroid Build Coastguard Worker       if (encoder.AffinityMode.NumBundleThreads * 2 <= encoder.AffinityMode.NumCores)
1866*f6dc9357SAndroid Build Coastguard Worker         encoder.AffinityMode.NumBundleThreads *= 2;
1867*f6dc9357SAndroid Build Coastguard Worker     }
1868*f6dc9357SAndroid Build Coastguard Worker     */
1869*f6dc9357SAndroid Build Coastguard Worker 
1870*f6dc9357SAndroid Build Coastguard Worker     #endif
1871*f6dc9357SAndroid Build Coastguard Worker 
1872*f6dc9357SAndroid Build Coastguard Worker     {
1873*f6dc9357SAndroid Build Coastguard Worker       CCreatedCoder cod;
1874*f6dc9357SAndroid Build Coastguard Worker       RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod))
1875*f6dc9357SAndroid Build Coastguard Worker       encoder._encoder = cod.Coder;
1876*f6dc9357SAndroid Build Coastguard Worker       if (!encoder._encoder && !encoder._encoderFilter)
1877*f6dc9357SAndroid Build Coastguard Worker         return E_NOTIMPL;
1878*f6dc9357SAndroid Build Coastguard Worker     }
1879*f6dc9357SAndroid Build Coastguard Worker 
1880*f6dc9357SAndroid Build Coastguard Worker     SetPseudoRand(encoder._iv,  sizeof(encoder._iv), 17);
1881*f6dc9357SAndroid Build Coastguard Worker     SetPseudoRand(encoder._key, sizeof(encoder._key), 51);
1882*f6dc9357SAndroid Build Coastguard Worker     SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123);
1883*f6dc9357SAndroid Build Coastguard Worker 
1884*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1885*f6dc9357SAndroid Build Coastguard Worker     {
1886*f6dc9357SAndroid Build Coastguard Worker       CCreatedCoder cod;
1887*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
1888*f6dc9357SAndroid Build Coastguard Worker       RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod))
1889*f6dc9357SAndroid Build Coastguard Worker       decoder = cod.Coder;
1890*f6dc9357SAndroid Build Coastguard Worker       if (!encoder._decoderFilter && !decoder)
1891*f6dc9357SAndroid Build Coastguard Worker         return E_NOTIMPL;
1892*f6dc9357SAndroid Build Coastguard Worker     }
1893*f6dc9357SAndroid Build Coastguard Worker 
1894*f6dc9357SAndroid Build Coastguard Worker     encoder.UseRealData_Enc =
1895*f6dc9357SAndroid Build Coastguard Worker     encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30;
1896*f6dc9357SAndroid Build Coastguard Worker 
1897*f6dc9357SAndroid Build Coastguard Worker     encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
1898*f6dc9357SAndroid Build Coastguard Worker     if (benchProps->DecComplexCompr +
1899*f6dc9357SAndroid Build Coastguard Worker         benchProps->DecComplexUnc <= 30)
1900*f6dc9357SAndroid Build Coastguard Worker       encoder.CheckCrcMode_Dec =
1901*f6dc9357SAndroid Build Coastguard Worker           k_CheckCrcMode_FirstPass; // for filters
1902*f6dc9357SAndroid Build Coastguard Worker           // k_CheckCrcMode_Never; // for debug
1903*f6dc9357SAndroid Build Coastguard Worker           // k_CheckCrcMode_Always; // for debug
1904*f6dc9357SAndroid Build Coastguard Worker     if (fileData)
1905*f6dc9357SAndroid Build Coastguard Worker     {
1906*f6dc9357SAndroid Build Coastguard Worker       encoder.UseRealData_Enc = true;
1907*f6dc9357SAndroid Build Coastguard Worker       encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always;
1908*f6dc9357SAndroid Build Coastguard Worker     }
1909*f6dc9357SAndroid Build Coastguard Worker   }
1910*f6dc9357SAndroid Build Coastguard Worker 
1911*f6dc9357SAndroid Build Coastguard Worker   UInt32 crc = 0;
1912*f6dc9357SAndroid Build Coastguard Worker   if (fileData)
1913*f6dc9357SAndroid Build Coastguard Worker     crc = CrcCalc(fileData, uncompressedDataSize);
1914*f6dc9357SAndroid Build Coastguard Worker 
1915*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
1916*f6dc9357SAndroid Build Coastguard Worker   {
1917*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo &encoder = encoders[i];
1918*f6dc9357SAndroid Build Coastguard Worker     encoder._method = method;
1919*f6dc9357SAndroid Build Coastguard Worker     encoder.generateDictBits = generateDictBits;
1920*f6dc9357SAndroid Build Coastguard Worker     encoder._uncompressedDataSize = uncompressedDataSize;
1921*f6dc9357SAndroid Build Coastguard Worker     encoder.kBufferSize = uncompressedDataSize;
1922*f6dc9357SAndroid Build Coastguard Worker     encoder.fileData = fileData;
1923*f6dc9357SAndroid Build Coastguard Worker     encoder.crc = crc;
1924*f6dc9357SAndroid Build Coastguard Worker   }
1925*f6dc9357SAndroid Build Coastguard Worker 
1926*f6dc9357SAndroid Build Coastguard Worker   CBenchProgressStatus status;
1927*f6dc9357SAndroid Build Coastguard Worker   status.Res = S_OK;
1928*f6dc9357SAndroid Build Coastguard Worker   status.EncodeMode = true;
1929*f6dc9357SAndroid Build Coastguard Worker 
1930*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
1931*f6dc9357SAndroid Build Coastguard Worker   CBenchThreadsFlusher encoderFlusher;
1932*f6dc9357SAndroid Build Coastguard Worker   if (mtEncMode)
1933*f6dc9357SAndroid Build Coastguard Worker   {
1934*f6dc9357SAndroid Build Coastguard Worker     WRes wres = encoderFlusher.Common.StartEvent.Create();
1935*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
1936*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
1937*f6dc9357SAndroid Build Coastguard Worker     encoderFlusher.NumThreads = numEncoderThreads;
1938*f6dc9357SAndroid Build Coastguard Worker     encoderFlusher.EncodersSpec = &encodersSpec;
1939*f6dc9357SAndroid Build Coastguard Worker     encoderFlusher.NeedClose = true;
1940*f6dc9357SAndroid Build Coastguard Worker   }
1941*f6dc9357SAndroid Build Coastguard Worker   #endif
1942*f6dc9357SAndroid Build Coastguard Worker 
1943*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
1944*f6dc9357SAndroid Build Coastguard Worker   {
1945*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo &encoder = encoders[i];
1946*f6dc9357SAndroid Build Coastguard Worker     encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands);
1947*f6dc9357SAndroid Build Coastguard Worker     // encoder.NumIterations = 3;
1948*f6dc9357SAndroid Build Coastguard Worker     {
1949*f6dc9357SAndroid Build Coastguard Worker #if 0
1950*f6dc9357SAndroid Build Coastguard Worker       #define kCrcPoly 0xEDB88320
1951*f6dc9357SAndroid Build Coastguard Worker       UInt32 r = i;
1952*f6dc9357SAndroid Build Coastguard Worker       unsigned num = numEncoderThreads < 256 ? 8 : 16;
1953*f6dc9357SAndroid Build Coastguard Worker       do
1954*f6dc9357SAndroid Build Coastguard Worker         r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
1955*f6dc9357SAndroid Build Coastguard Worker       while (--num);
1956*f6dc9357SAndroid Build Coastguard Worker       encoder.Salt = r;
1957*f6dc9357SAndroid Build Coastguard Worker #else
1958*f6dc9357SAndroid Build Coastguard Worker       UInt32 salt0 = g_CrcTable[(Byte)i];
1959*f6dc9357SAndroid Build Coastguard Worker       UInt32 salt1 = g_CrcTable[(Byte)(i >> 8)];
1960*f6dc9357SAndroid Build Coastguard Worker       encoder.Salt = salt0 ^ (salt1 << 3);
1961*f6dc9357SAndroid Build Coastguard Worker #endif
1962*f6dc9357SAndroid Build Coastguard Worker     }
1963*f6dc9357SAndroid Build Coastguard Worker 
1964*f6dc9357SAndroid Build Coastguard Worker     // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread
1965*f6dc9357SAndroid Build Coastguard Worker     // printf("\n encoder index = %d, Salt = %8x\n", i, encoder.Salt);
1966*f6dc9357SAndroid Build Coastguard Worker 
1967*f6dc9357SAndroid Build Coastguard Worker     encoder.KeySize = benchProps->KeySize;
1968*f6dc9357SAndroid Build Coastguard Worker 
1969*f6dc9357SAndroid Build Coastguard Worker     for (int j = 0; j < 2; j++)
1970*f6dc9357SAndroid Build Coastguard Worker     {
1971*f6dc9357SAndroid Build Coastguard Worker       CBenchProgressInfo *spec = new CBenchProgressInfo;
1972*f6dc9357SAndroid Build Coastguard Worker       encoder.progressInfoSpec[j] = spec;
1973*f6dc9357SAndroid Build Coastguard Worker       encoder.progressInfo[j] = spec;
1974*f6dc9357SAndroid Build Coastguard Worker       spec->Status = &status;
1975*f6dc9357SAndroid Build Coastguard Worker     }
1976*f6dc9357SAndroid Build Coastguard Worker 
1977*f6dc9357SAndroid Build Coastguard Worker     if (i == 0)
1978*f6dc9357SAndroid Build Coastguard Worker     {
1979*f6dc9357SAndroid Build Coastguard Worker       CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
1980*f6dc9357SAndroid Build Coastguard Worker       bpi->Callback = callback;
1981*f6dc9357SAndroid Build Coastguard Worker       bpi->BenchInfo.NumIterations = numEncoderThreads;
1982*f6dc9357SAndroid Build Coastguard Worker     }
1983*f6dc9357SAndroid Build Coastguard Worker 
1984*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1985*f6dc9357SAndroid Build Coastguard Worker     if (mtEncMode)
1986*f6dc9357SAndroid Build Coastguard Worker     {
1987*f6dc9357SAndroid Build Coastguard Worker       #ifdef USE_ALLOCA
1988*f6dc9357SAndroid Build Coastguard Worker       encoder.AllocaSize = BENCH_ALLOCA_VALUE(i);
1989*f6dc9357SAndroid Build Coastguard Worker       #endif
1990*f6dc9357SAndroid Build Coastguard Worker 
1991*f6dc9357SAndroid Build Coastguard Worker       encoder.Common = &encoderFlusher.Common;
1992*f6dc9357SAndroid Build Coastguard Worker       encoder.IsGlobalMtMode = numEncoderThreads > 1;
1993*f6dc9357SAndroid Build Coastguard Worker       RINOK(encoder.CreateEncoderThread())
1994*f6dc9357SAndroid Build Coastguard Worker     }
1995*f6dc9357SAndroid Build Coastguard Worker     #endif
1996*f6dc9357SAndroid Build Coastguard Worker   }
1997*f6dc9357SAndroid Build Coastguard Worker 
1998*f6dc9357SAndroid Build Coastguard Worker   if (printCallback)
1999*f6dc9357SAndroid Build Coastguard Worker   {
2000*f6dc9357SAndroid Build Coastguard Worker     RINOK(printCallback->CheckBreak())
2001*f6dc9357SAndroid Build Coastguard Worker   }
2002*f6dc9357SAndroid Build Coastguard Worker 
2003*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2004*f6dc9357SAndroid Build Coastguard Worker   if (mtEncMode)
2005*f6dc9357SAndroid Build Coastguard Worker   {
2006*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numEncoderThreads; i++)
2007*f6dc9357SAndroid Build Coastguard Worker     {
2008*f6dc9357SAndroid Build Coastguard Worker       CEncoderInfo &encoder = encoders[i];
2009*f6dc9357SAndroid Build Coastguard Worker       const WRes wres = encoder.ReadyEvent.Lock();
2010*f6dc9357SAndroid Build Coastguard Worker       if (wres != 0)
2011*f6dc9357SAndroid Build Coastguard Worker         return HRESULT_FROM_WIN32(wres);
2012*f6dc9357SAndroid Build Coastguard Worker       RINOK(encoder.Results[0])
2013*f6dc9357SAndroid Build Coastguard Worker     }
2014*f6dc9357SAndroid Build Coastguard Worker 
2015*f6dc9357SAndroid Build Coastguard Worker     CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0];
2016*f6dc9357SAndroid Build Coastguard Worker     bpi->SetStartTime();
2017*f6dc9357SAndroid Build Coastguard Worker 
2018*f6dc9357SAndroid Build Coastguard Worker     const WRes wres = encoderFlusher.StartAndWait();
2019*f6dc9357SAndroid Build Coastguard Worker     if (status.Res == 0 && wres != 0)
2020*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
2021*f6dc9357SAndroid Build Coastguard Worker   }
2022*f6dc9357SAndroid Build Coastguard Worker   else
2023*f6dc9357SAndroid Build Coastguard Worker   #endif
2024*f6dc9357SAndroid Build Coastguard Worker   {
2025*f6dc9357SAndroid Build Coastguard Worker     RINOK(encoders[0].Encode())
2026*f6dc9357SAndroid Build Coastguard Worker   }
2027*f6dc9357SAndroid Build Coastguard Worker 
2028*f6dc9357SAndroid Build Coastguard Worker   RINOK(status.Res)
2029*f6dc9357SAndroid Build Coastguard Worker 
2030*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo info;
2031*f6dc9357SAndroid Build Coastguard Worker 
2032*f6dc9357SAndroid Build Coastguard Worker   encoders[0].progressInfoSpec[0]->SetFinishTime(info);
2033*f6dc9357SAndroid Build Coastguard Worker   info.UnpackSize = 0;
2034*f6dc9357SAndroid Build Coastguard Worker   info.PackSize = 0;
2035*f6dc9357SAndroid Build Coastguard Worker   info.NumIterations = encoders[0].NumIterations;
2036*f6dc9357SAndroid Build Coastguard Worker 
2037*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
2038*f6dc9357SAndroid Build Coastguard Worker   {
2039*f6dc9357SAndroid Build Coastguard Worker     const CEncoderInfo &encoder = encoders[i];
2040*f6dc9357SAndroid Build Coastguard Worker     info.UnpackSize += encoder.kBufferSize;
2041*f6dc9357SAndroid Build Coastguard Worker     info.PackSize += encoder.compressedSize;
2042*f6dc9357SAndroid Build Coastguard Worker     // printf("\n%7d\n", encoder.compressedSize);
2043*f6dc9357SAndroid Build Coastguard Worker   }
2044*f6dc9357SAndroid Build Coastguard Worker 
2045*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->SetEncodeResult(info, true))
2046*f6dc9357SAndroid Build Coastguard Worker 
2047*f6dc9357SAndroid Build Coastguard Worker 
2048*f6dc9357SAndroid Build Coastguard Worker 
2049*f6dc9357SAndroid Build Coastguard Worker 
2050*f6dc9357SAndroid Build Coastguard Worker   // ---------- Decode ----------
2051*f6dc9357SAndroid Build Coastguard Worker 
2052*f6dc9357SAndroid Build Coastguard Worker   status.Res = S_OK;
2053*f6dc9357SAndroid Build Coastguard Worker   status.EncodeMode = false;
2054*f6dc9357SAndroid Build Coastguard Worker 
2055*f6dc9357SAndroid Build Coastguard Worker   const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
2056*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2057*f6dc9357SAndroid Build Coastguard Worker   const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity();
2058*f6dc9357SAndroid Build Coastguard Worker   #endif
2059*f6dc9357SAndroid Build Coastguard Worker 
2060*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
2061*f6dc9357SAndroid Build Coastguard Worker   {
2062*f6dc9357SAndroid Build Coastguard Worker     CEncoderInfo &encoder = encoders[i];
2063*f6dc9357SAndroid Build Coastguard Worker 
2064*f6dc9357SAndroid Build Coastguard Worker     /*
2065*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
2066*f6dc9357SAndroid Build Coastguard Worker     // encoder.affinityMode = *affinityMode;
2067*f6dc9357SAndroid Build Coastguard Worker     if (encoder.NumEncoderInternalThreads != 1)
2068*f6dc9357SAndroid Build Coastguard Worker       encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads;
2069*f6dc9357SAndroid Build Coastguard Worker     #endif
2070*f6dc9357SAndroid Build Coastguard Worker     */
2071*f6dc9357SAndroid Build Coastguard Worker 
2072*f6dc9357SAndroid Build Coastguard Worker 
2073*f6dc9357SAndroid Build Coastguard Worker     if (i == 0)
2074*f6dc9357SAndroid Build Coastguard Worker     {
2075*f6dc9357SAndroid Build Coastguard Worker       encoder.NumIterations = GetNumIterations(
2076*f6dc9357SAndroid Build Coastguard Worker           benchProps->GetNumCommands_Dec(
2077*f6dc9357SAndroid Build Coastguard Worker               encoder.compressedSize,
2078*f6dc9357SAndroid Build Coastguard Worker               encoder.kBufferSize),
2079*f6dc9357SAndroid Build Coastguard Worker           complexInCommands);
2080*f6dc9357SAndroid Build Coastguard Worker       CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
2081*f6dc9357SAndroid Build Coastguard Worker       bpi->Callback = callback;
2082*f6dc9357SAndroid Build Coastguard Worker       bpi->BenchInfo.NumIterations = numDecoderThreads;
2083*f6dc9357SAndroid Build Coastguard Worker       bpi->SetStartTime();
2084*f6dc9357SAndroid Build Coastguard Worker     }
2085*f6dc9357SAndroid Build Coastguard Worker     else
2086*f6dc9357SAndroid Build Coastguard Worker       encoder.NumIterations = encoders[0].NumIterations;
2087*f6dc9357SAndroid Build Coastguard Worker 
2088*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
2089*f6dc9357SAndroid Build Coastguard Worker     {
2090*f6dc9357SAndroid Build Coastguard Worker       const int numSubThreads = method.Get_NumThreads();
2091*f6dc9357SAndroid Build Coastguard Worker       encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads;
2092*f6dc9357SAndroid Build Coastguard Worker     }
2093*f6dc9357SAndroid Build Coastguard Worker     if (mtDecoderMode)
2094*f6dc9357SAndroid Build Coastguard Worker     {
2095*f6dc9357SAndroid Build Coastguard Worker       for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2096*f6dc9357SAndroid Build Coastguard Worker       {
2097*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
2098*f6dc9357SAndroid Build Coastguard Worker             #ifdef USE_ALLOCA
2099*f6dc9357SAndroid Build Coastguard Worker             , BENCH_ALLOCA_VALUE(i * numSubDecoderThreads + j)
2100*f6dc9357SAndroid Build Coastguard Worker             #endif
2101*f6dc9357SAndroid Build Coastguard Worker             );
2102*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
2103*f6dc9357SAndroid Build Coastguard Worker       }
2104*f6dc9357SAndroid Build Coastguard Worker     }
2105*f6dc9357SAndroid Build Coastguard Worker     else
2106*f6dc9357SAndroid Build Coastguard Worker     #endif
2107*f6dc9357SAndroid Build Coastguard Worker     {
2108*f6dc9357SAndroid Build Coastguard Worker       RINOK(encoder.Decode(0))
2109*f6dc9357SAndroid Build Coastguard Worker     }
2110*f6dc9357SAndroid Build Coastguard Worker   }
2111*f6dc9357SAndroid Build Coastguard Worker 
2112*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2113*f6dc9357SAndroid Build Coastguard Worker   if (mtDecoderMode)
2114*f6dc9357SAndroid Build Coastguard Worker   {
2115*f6dc9357SAndroid Build Coastguard Worker     WRes wres = 0;
2116*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = S_OK;
2117*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numEncoderThreads; i++)
2118*f6dc9357SAndroid Build Coastguard Worker       for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2119*f6dc9357SAndroid Build Coastguard Worker       {
2120*f6dc9357SAndroid Build Coastguard Worker         CEncoderInfo &encoder = encoders[i];
2121*f6dc9357SAndroid Build Coastguard Worker         const WRes wres2 = encoder.thread[j].
2122*f6dc9357SAndroid Build Coastguard Worker             // Wait(); // later we can get thread times from thread in UNDER_CE
2123*f6dc9357SAndroid Build Coastguard Worker             Wait_Close();
2124*f6dc9357SAndroid Build Coastguard Worker         if (wres == 0 && wres2 != 0)
2125*f6dc9357SAndroid Build Coastguard Worker           wres = wres2;
2126*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res2 = encoder.Results[j];
2127*f6dc9357SAndroid Build Coastguard Worker         if (res == 0 && res2 != 0)
2128*f6dc9357SAndroid Build Coastguard Worker           res = res2;
2129*f6dc9357SAndroid Build Coastguard Worker       }
2130*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
2131*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
2132*f6dc9357SAndroid Build Coastguard Worker     RINOK(res)
2133*f6dc9357SAndroid Build Coastguard Worker   }
2134*f6dc9357SAndroid Build Coastguard Worker   #endif // Z7_ST
2135*f6dc9357SAndroid Build Coastguard Worker 
2136*f6dc9357SAndroid Build Coastguard Worker   RINOK(status.Res)
2137*f6dc9357SAndroid Build Coastguard Worker   encoders[0].progressInfoSpec[0]->SetFinishTime(info);
2138*f6dc9357SAndroid Build Coastguard Worker 
2139*f6dc9357SAndroid Build Coastguard Worker   /*
2140*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2141*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
2142*f6dc9357SAndroid Build Coastguard Worker   if (mtDecoderMode)
2143*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numEncoderThreads; i++)
2144*f6dc9357SAndroid Build Coastguard Worker       for (UInt32 j = 0; j < numSubDecoderThreads; j++)
2145*f6dc9357SAndroid Build Coastguard Worker       {
2146*f6dc9357SAndroid Build Coastguard Worker         FILETIME creationTime, exitTime, kernelTime, userTime;
2147*f6dc9357SAndroid Build Coastguard Worker         if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0)
2148*f6dc9357SAndroid Build Coastguard Worker           info.UserTime += GetTime64(userTime) + GetTime64(kernelTime);
2149*f6dc9357SAndroid Build Coastguard Worker       }
2150*f6dc9357SAndroid Build Coastguard Worker   #endif
2151*f6dc9357SAndroid Build Coastguard Worker   #endif
2152*f6dc9357SAndroid Build Coastguard Worker   */
2153*f6dc9357SAndroid Build Coastguard Worker 
2154*f6dc9357SAndroid Build Coastguard Worker   info.UnpackSize = 0;
2155*f6dc9357SAndroid Build Coastguard Worker   info.PackSize = 0;
2156*f6dc9357SAndroid Build Coastguard Worker   info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
2157*f6dc9357SAndroid Build Coastguard Worker 
2158*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numEncoderThreads; i++)
2159*f6dc9357SAndroid Build Coastguard Worker   {
2160*f6dc9357SAndroid Build Coastguard Worker     const CEncoderInfo &encoder = encoders[i];
2161*f6dc9357SAndroid Build Coastguard Worker     info.UnpackSize += encoder.kBufferSize;
2162*f6dc9357SAndroid Build Coastguard Worker     info.PackSize += encoder.compressedSize;
2163*f6dc9357SAndroid Build Coastguard Worker   }
2164*f6dc9357SAndroid Build Coastguard Worker 
2165*f6dc9357SAndroid Build Coastguard Worker   // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ??
2166*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->SetDecodeResult(info, true))
2167*f6dc9357SAndroid Build Coastguard Worker 
2168*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
2169*f6dc9357SAndroid Build Coastguard Worker }
2170*f6dc9357SAndroid Build Coastguard Worker 
2171*f6dc9357SAndroid Build Coastguard Worker 
2172*f6dc9357SAndroid Build Coastguard Worker 
2173*f6dc9357SAndroid Build Coastguard Worker static inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog)
2174*f6dc9357SAndroid Build Coastguard Worker {
2175*f6dc9357SAndroid Build Coastguard Worker   /*
2176*f6dc9357SAndroid Build Coastguard Worker   if (dictSizeLog < 32)
2177*f6dc9357SAndroid Build Coastguard Worker     return (UInt32)1 << dictSizeLog;
2178*f6dc9357SAndroid Build Coastguard Worker   else
2179*f6dc9357SAndroid Build Coastguard Worker     return (UInt32)(Int32)-1;
2180*f6dc9357SAndroid Build Coastguard Worker   */
2181*f6dc9357SAndroid Build Coastguard Worker   return (UInt64)1 << dictSizeLog;
2182*f6dc9357SAndroid Build Coastguard Worker }
2183*f6dc9357SAndroid Build Coastguard Worker 
2184*f6dc9357SAndroid Build Coastguard Worker 
2185*f6dc9357SAndroid Build Coastguard Worker // it's limit of current LZMA implementation that can be changed later
2186*f6dc9357SAndroid Build Coastguard Worker #define kLzmaMaxDictSize ((UInt32)15 << 28)
2187*f6dc9357SAndroid Build Coastguard Worker 
2188*f6dc9357SAndroid Build Coastguard Worker static inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict)
2189*f6dc9357SAndroid Build Coastguard Worker {
2190*f6dc9357SAndroid Build Coastguard Worker   if (dict == 0)
2191*f6dc9357SAndroid Build Coastguard Worker     dict = 1;
2192*f6dc9357SAndroid Build Coastguard Worker   if (dict > kLzmaMaxDictSize)
2193*f6dc9357SAndroid Build Coastguard Worker     dict = kLzmaMaxDictSize;
2194*f6dc9357SAndroid Build Coastguard Worker   UInt32 hs = (UInt32)dict - 1;
2195*f6dc9357SAndroid Build Coastguard Worker   hs |= (hs >> 1);
2196*f6dc9357SAndroid Build Coastguard Worker   hs |= (hs >> 2);
2197*f6dc9357SAndroid Build Coastguard Worker   hs |= (hs >> 4);
2198*f6dc9357SAndroid Build Coastguard Worker   hs |= (hs >> 8);
2199*f6dc9357SAndroid Build Coastguard Worker   hs >>= 1;
2200*f6dc9357SAndroid Build Coastguard Worker   hs |= 0xFFFF;
2201*f6dc9357SAndroid Build Coastguard Worker   if (hs > (1 << 24))
2202*f6dc9357SAndroid Build Coastguard Worker     hs >>= 1;
2203*f6dc9357SAndroid Build Coastguard Worker   hs++;
2204*f6dc9357SAndroid Build Coastguard Worker   hs += (1 << 16);
2205*f6dc9357SAndroid Build Coastguard Worker 
2206*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
2207*f6dc9357SAndroid Build Coastguard Worker   UInt64 blockSize = (UInt64)dict + (1 << 16)
2208*f6dc9357SAndroid Build Coastguard Worker       + (multiThread ? (1 << 20) : 0);
2209*f6dc9357SAndroid Build Coastguard Worker   blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
2210*f6dc9357SAndroid Build Coastguard Worker   if (blockSize >= kBlockSizeMax)
2211*f6dc9357SAndroid Build Coastguard Worker     blockSize = kBlockSizeMax;
2212*f6dc9357SAndroid Build Coastguard Worker 
2213*f6dc9357SAndroid Build Coastguard Worker   UInt64 son = (UInt64)dict;
2214*f6dc9357SAndroid Build Coastguard Worker   if (btMode)
2215*f6dc9357SAndroid Build Coastguard Worker     son *= 2;
2216*f6dc9357SAndroid Build Coastguard Worker   const UInt64 v = (hs + son) * 4 + blockSize +
2217*f6dc9357SAndroid Build Coastguard Worker       (1 << 20) + (multiThread ? (6 << 20) : 0);
2218*f6dc9357SAndroid Build Coastguard Worker 
2219*f6dc9357SAndroid Build Coastguard Worker   // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20));
2220*f6dc9357SAndroid Build Coastguard Worker   // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20));
2221*f6dc9357SAndroid Build Coastguard Worker   return v;
2222*f6dc9357SAndroid Build Coastguard Worker }
2223*f6dc9357SAndroid Build Coastguard Worker 
2224*f6dc9357SAndroid Build Coastguard Worker 
2225*f6dc9357SAndroid Build Coastguard Worker UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench)
2226*f6dc9357SAndroid Build Coastguard Worker {
2227*f6dc9357SAndroid Build Coastguard Worker   const size_t kBufferSize = (size_t)dictionary + kAdditionalSize;
2228*f6dc9357SAndroid Build Coastguard Worker   const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2;
2229*f6dc9357SAndroid Build Coastguard Worker   if (level < 0)
2230*f6dc9357SAndroid Build Coastguard Worker     level = 5;
2231*f6dc9357SAndroid Build Coastguard Worker   const int algo = (level < 5 ? 0 : 1);
2232*f6dc9357SAndroid Build Coastguard Worker   const int btMode = (algo == 0 ? 0 : 1);
2233*f6dc9357SAndroid Build Coastguard Worker 
2234*f6dc9357SAndroid Build Coastguard Worker   UInt32 numBigThreads = numThreads;
2235*f6dc9357SAndroid Build Coastguard Worker   const bool lzmaMt = (totalBench || (numThreads > 1 && btMode));
2236*f6dc9357SAndroid Build Coastguard Worker   if (btMode)
2237*f6dc9357SAndroid Build Coastguard Worker   {
2238*f6dc9357SAndroid Build Coastguard Worker     if (!totalBench && lzmaMt)
2239*f6dc9357SAndroid Build Coastguard Worker       numBigThreads /= 2;
2240*f6dc9357SAndroid Build Coastguard Worker   }
2241*f6dc9357SAndroid Build Coastguard Worker   return ((UInt64)kBufferSize + kCompressedBufferSize +
2242*f6dc9357SAndroid Build Coastguard Worker     GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads;
2243*f6dc9357SAndroid Build Coastguard Worker }
2244*f6dc9357SAndroid Build Coastguard Worker 
2245*f6dc9357SAndroid Build Coastguard Worker static UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary)
2246*f6dc9357SAndroid Build Coastguard Worker {
2247*f6dc9357SAndroid Build Coastguard Worker   // dictionary += (dictionary >> 9); // for page tables (virtual memory)
2248*f6dc9357SAndroid Build Coastguard Worker   return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20);
2249*f6dc9357SAndroid Build Coastguard Worker }
2250*f6dc9357SAndroid Build Coastguard Worker 
2251*f6dc9357SAndroid Build Coastguard Worker 
2252*f6dc9357SAndroid Build Coastguard Worker // ---------- CRC and HASH ----------
2253*f6dc9357SAndroid Build Coastguard Worker 
2254*f6dc9357SAndroid Build Coastguard Worker struct CCrcInfo_Base
2255*f6dc9357SAndroid Build Coastguard Worker {
2256*f6dc9357SAndroid Build Coastguard Worker   CMidAlignedBuffer Buffer;
2257*f6dc9357SAndroid Build Coastguard Worker   const Byte *Data;
2258*f6dc9357SAndroid Build Coastguard Worker   size_t Size;
2259*f6dc9357SAndroid Build Coastguard Worker   bool CreateLocalBuf;
2260*f6dc9357SAndroid Build Coastguard Worker   UInt32 CheckSum_Res;
2261*f6dc9357SAndroid Build Coastguard Worker 
2262*f6dc9357SAndroid Build Coastguard Worker   CCrcInfo_Base(): CreateLocalBuf(true), CheckSum_Res(0) {}
2263*f6dc9357SAndroid Build Coastguard Worker 
2264*f6dc9357SAndroid Build Coastguard Worker   HRESULT Generate(const Byte *data, size_t size);
2265*f6dc9357SAndroid Build Coastguard Worker   HRESULT CrcProcess(UInt64 numIterations,
2266*f6dc9357SAndroid Build Coastguard Worker       const UInt32 *checkSum, IHasher *hf,
2267*f6dc9357SAndroid Build Coastguard Worker       IBenchPrintCallback *callback);
2268*f6dc9357SAndroid Build Coastguard Worker };
2269*f6dc9357SAndroid Build Coastguard Worker 
2270*f6dc9357SAndroid Build Coastguard Worker 
2271*f6dc9357SAndroid Build Coastguard Worker // for debug: define it to test hash calling with unaligned data
2272*f6dc9357SAndroid Build Coastguard Worker // #define Z7_BENCH_HASH_ALIGN_BUF_OFFSET  3
2273*f6dc9357SAndroid Build Coastguard Worker 
2274*f6dc9357SAndroid Build Coastguard Worker HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size)
2275*f6dc9357SAndroid Build Coastguard Worker {
2276*f6dc9357SAndroid Build Coastguard Worker   Size = size;
2277*f6dc9357SAndroid Build Coastguard Worker   Data = data;
2278*f6dc9357SAndroid Build Coastguard Worker   if (!data || CreateLocalBuf)
2279*f6dc9357SAndroid Build Coastguard Worker   {
2280*f6dc9357SAndroid Build Coastguard Worker     Byte *buf;
2281*f6dc9357SAndroid Build Coastguard Worker     const size_t size2 = (size + k_RandBuf_AlignMask) & ~(size_t)k_RandBuf_AlignMask;
2282*f6dc9357SAndroid Build Coastguard Worker     if (size2 < size)
2283*f6dc9357SAndroid Build Coastguard Worker       return E_OUTOFMEMORY;
2284*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_BENCH_HASH_ALIGN_BUF_OFFSET
2285*f6dc9357SAndroid Build Coastguard Worker     ALLOC_WITH_HRESULT(&Buffer, size2 + Z7_BENCH_HASH_ALIGN_BUF_OFFSET)
2286*f6dc9357SAndroid Build Coastguard Worker     buf = Buffer + Z7_BENCH_HASH_ALIGN_BUF_OFFSET;
2287*f6dc9357SAndroid Build Coastguard Worker #else
2288*f6dc9357SAndroid Build Coastguard Worker     ALLOC_WITH_HRESULT(&Buffer, size2)
2289*f6dc9357SAndroid Build Coastguard Worker     buf = Buffer;
2290*f6dc9357SAndroid Build Coastguard Worker #endif
2291*f6dc9357SAndroid Build Coastguard Worker     Data = buf;
2292*f6dc9357SAndroid Build Coastguard Worker     if (!data)
2293*f6dc9357SAndroid Build Coastguard Worker       RandGen_BufAfterPad(buf, size);
2294*f6dc9357SAndroid Build Coastguard Worker     else if (size != 0) // (CreateLocalBuf == true)
2295*f6dc9357SAndroid Build Coastguard Worker       memcpy(buf, data, size);
2296*f6dc9357SAndroid Build Coastguard Worker   }
2297*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
2298*f6dc9357SAndroid Build Coastguard Worker }
2299*f6dc9357SAndroid Build Coastguard Worker 
2300*f6dc9357SAndroid Build Coastguard Worker 
2301*f6dc9357SAndroid Build Coastguard Worker #if 1
2302*f6dc9357SAndroid Build Coastguard Worker #define HashUpdate(hf, data, size)  hf->Update(data, size)
2303*f6dc9357SAndroid Build Coastguard Worker #else
2304*f6dc9357SAndroid Build Coastguard Worker // for debug:
2305*f6dc9357SAndroid Build Coastguard Worker static void HashUpdate(IHasher *hf, const void *data, UInt32 size)
2306*f6dc9357SAndroid Build Coastguard Worker {
2307*f6dc9357SAndroid Build Coastguard Worker   for (;;)
2308*f6dc9357SAndroid Build Coastguard Worker   {
2309*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
2310*f6dc9357SAndroid Build Coastguard Worker       return;
2311*f6dc9357SAndroid Build Coastguard Worker     UInt32 size2 = (size * 0x85EBCA87) % size / 8;
2312*f6dc9357SAndroid Build Coastguard Worker     // UInt32 size2 = size / 2;
2313*f6dc9357SAndroid Build Coastguard Worker     if (size2 == 0)
2314*f6dc9357SAndroid Build Coastguard Worker       size2 = 1;
2315*f6dc9357SAndroid Build Coastguard Worker     hf->Update(data, size2);
2316*f6dc9357SAndroid Build Coastguard Worker     data = (const void *)((const Byte *)data + size2);
2317*f6dc9357SAndroid Build Coastguard Worker     size -= size2;
2318*f6dc9357SAndroid Build Coastguard Worker   }
2319*f6dc9357SAndroid Build Coastguard Worker }
2320*f6dc9357SAndroid Build Coastguard Worker #endif
2321*f6dc9357SAndroid Build Coastguard Worker 
2322*f6dc9357SAndroid Build Coastguard Worker 
2323*f6dc9357SAndroid Build Coastguard Worker HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
2324*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *checkSum, IHasher *hf,
2325*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *callback)
2326*f6dc9357SAndroid Build Coastguard Worker {
2327*f6dc9357SAndroid Build Coastguard Worker   MY_ALIGN(16)
2328*f6dc9357SAndroid Build Coastguard Worker   UInt32 hash32[64 / 4];
2329*f6dc9357SAndroid Build Coastguard Worker   memset(hash32, 0, sizeof(hash32));
2330*f6dc9357SAndroid Build Coastguard Worker 
2331*f6dc9357SAndroid Build Coastguard Worker   CheckSum_Res = 0;
2332*f6dc9357SAndroid Build Coastguard Worker 
2333*f6dc9357SAndroid Build Coastguard Worker   const UInt32 hashSize = hf->GetDigestSize();
2334*f6dc9357SAndroid Build Coastguard Worker   if (hashSize > sizeof(hash32))
2335*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
2336*f6dc9357SAndroid Build Coastguard Worker 
2337*f6dc9357SAndroid Build Coastguard Worker   const Byte *buf = Data;
2338*f6dc9357SAndroid Build Coastguard Worker   const size_t size = Size;
2339*f6dc9357SAndroid Build Coastguard Worker   UInt32 checkSum_Prev = 0;
2340*f6dc9357SAndroid Build Coastguard Worker 
2341*f6dc9357SAndroid Build Coastguard Worker   UInt64 prev = 0;
2342*f6dc9357SAndroid Build Coastguard Worker   UInt64 cur = 0;
2343*f6dc9357SAndroid Build Coastguard Worker 
2344*f6dc9357SAndroid Build Coastguard Worker   do
2345*f6dc9357SAndroid Build Coastguard Worker   {
2346*f6dc9357SAndroid Build Coastguard Worker     hf->Init();
2347*f6dc9357SAndroid Build Coastguard Worker     size_t pos = 0;
2348*f6dc9357SAndroid Build Coastguard Worker     do
2349*f6dc9357SAndroid Build Coastguard Worker     {
2350*f6dc9357SAndroid Build Coastguard Worker       const size_t rem = size - pos;
2351*f6dc9357SAndroid Build Coastguard Worker       const UInt32 kStep = ((UInt32)1 << 31);
2352*f6dc9357SAndroid Build Coastguard Worker       const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
2353*f6dc9357SAndroid Build Coastguard Worker       HashUpdate(hf, buf + pos, curSize);
2354*f6dc9357SAndroid Build Coastguard Worker       pos += curSize;
2355*f6dc9357SAndroid Build Coastguard Worker     }
2356*f6dc9357SAndroid Build Coastguard Worker     while (pos != size);
2357*f6dc9357SAndroid Build Coastguard Worker 
2358*f6dc9357SAndroid Build Coastguard Worker     hf->Final((Byte *)(void *)hash32);
2359*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum = 0;
2360*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 j = 0; j < hashSize; j += 4)
2361*f6dc9357SAndroid Build Coastguard Worker     {
2362*f6dc9357SAndroid Build Coastguard Worker       sum = rotlFixed(sum, 11);
2363*f6dc9357SAndroid Build Coastguard Worker       sum += GetUi32((const Byte *)(const void *)hash32 + j);
2364*f6dc9357SAndroid Build Coastguard Worker     }
2365*f6dc9357SAndroid Build Coastguard Worker     if (checkSum)
2366*f6dc9357SAndroid Build Coastguard Worker     {
2367*f6dc9357SAndroid Build Coastguard Worker       if (sum != *checkSum)
2368*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
2369*f6dc9357SAndroid Build Coastguard Worker     }
2370*f6dc9357SAndroid Build Coastguard Worker     else
2371*f6dc9357SAndroid Build Coastguard Worker     {
2372*f6dc9357SAndroid Build Coastguard Worker       checkSum_Prev = sum;
2373*f6dc9357SAndroid Build Coastguard Worker       checkSum = &checkSum_Prev;
2374*f6dc9357SAndroid Build Coastguard Worker     }
2375*f6dc9357SAndroid Build Coastguard Worker     if (callback)
2376*f6dc9357SAndroid Build Coastguard Worker     {
2377*f6dc9357SAndroid Build Coastguard Worker       cur += size;
2378*f6dc9357SAndroid Build Coastguard Worker       if (cur - prev >= ((UInt32)1 << 30))
2379*f6dc9357SAndroid Build Coastguard Worker       {
2380*f6dc9357SAndroid Build Coastguard Worker         prev = cur;
2381*f6dc9357SAndroid Build Coastguard Worker         RINOK(callback->CheckBreak())
2382*f6dc9357SAndroid Build Coastguard Worker       }
2383*f6dc9357SAndroid Build Coastguard Worker     }
2384*f6dc9357SAndroid Build Coastguard Worker   }
2385*f6dc9357SAndroid Build Coastguard Worker   while (--numIterations);
2386*f6dc9357SAndroid Build Coastguard Worker 
2387*f6dc9357SAndroid Build Coastguard Worker   CheckSum_Res = checkSum_Prev;
2388*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
2389*f6dc9357SAndroid Build Coastguard Worker }
2390*f6dc9357SAndroid Build Coastguard Worker 
2391*f6dc9357SAndroid Build Coastguard Worker extern
2392*f6dc9357SAndroid Build Coastguard Worker UInt32 g_BenchCpuFreqTemp; // we need non-static variavble to disable compiler optimization
2393*f6dc9357SAndroid Build Coastguard Worker UInt32 g_BenchCpuFreqTemp = 1;
2394*f6dc9357SAndroid Build Coastguard Worker 
2395*f6dc9357SAndroid Build Coastguard Worker #define YY1 sum += val; sum ^= val;
2396*f6dc9357SAndroid Build Coastguard Worker #define YY3 YY1 YY1 YY1 YY1
2397*f6dc9357SAndroid Build Coastguard Worker #define YY5 YY3 YY3 YY3 YY3
2398*f6dc9357SAndroid Build Coastguard Worker #define YY7 YY5 YY5 YY5 YY5
2399*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kNumFreqCommands = 128;
2400*f6dc9357SAndroid Build Coastguard Worker 
2401*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
2402*f6dc9357SAndroid Build Coastguard Worker 
2403*f6dc9357SAndroid Build Coastguard Worker static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
2404*f6dc9357SAndroid Build Coastguard Worker {
2405*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < num; i++)
2406*f6dc9357SAndroid Build Coastguard Worker   {
2407*f6dc9357SAndroid Build Coastguard Worker     YY7
2408*f6dc9357SAndroid Build Coastguard Worker   }
2409*f6dc9357SAndroid Build Coastguard Worker   return sum;
2410*f6dc9357SAndroid Build Coastguard Worker }
2411*f6dc9357SAndroid Build Coastguard Worker 
2412*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
2413*f6dc9357SAndroid Build Coastguard Worker 
2414*f6dc9357SAndroid Build Coastguard Worker 
2415*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
2416*f6dc9357SAndroid Build Coastguard Worker 
2417*f6dc9357SAndroid Build Coastguard Worker struct CBaseThreadInfo
2418*f6dc9357SAndroid Build Coastguard Worker {
2419*f6dc9357SAndroid Build Coastguard Worker   NWindows::CThread Thread;
2420*f6dc9357SAndroid Build Coastguard Worker   IBenchPrintCallback *Callback;
2421*f6dc9357SAndroid Build Coastguard Worker   HRESULT CallbackRes;
2422*f6dc9357SAndroid Build Coastguard Worker 
2423*f6dc9357SAndroid Build Coastguard Worker   WRes Wait_If_Created()
2424*f6dc9357SAndroid Build Coastguard Worker   {
2425*f6dc9357SAndroid Build Coastguard Worker     if (!Thread.IsCreated())
2426*f6dc9357SAndroid Build Coastguard Worker       return 0;
2427*f6dc9357SAndroid Build Coastguard Worker     return Thread.Wait_Close();
2428*f6dc9357SAndroid Build Coastguard Worker   }
2429*f6dc9357SAndroid Build Coastguard Worker };
2430*f6dc9357SAndroid Build Coastguard Worker 
2431*f6dc9357SAndroid Build Coastguard Worker struct CFreqInfo: public CBaseThreadInfo
2432*f6dc9357SAndroid Build Coastguard Worker {
2433*f6dc9357SAndroid Build Coastguard Worker   UInt32 ValRes;
2434*f6dc9357SAndroid Build Coastguard Worker   UInt32 Size;
2435*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumIterations;
2436*f6dc9357SAndroid Build Coastguard Worker };
2437*f6dc9357SAndroid Build Coastguard Worker 
2438*f6dc9357SAndroid Build Coastguard Worker static THREAD_FUNC_DECL FreqThreadFunction(void *param)
2439*f6dc9357SAndroid Build Coastguard Worker {
2440*f6dc9357SAndroid Build Coastguard Worker   CFreqInfo *p = (CFreqInfo *)param;
2441*f6dc9357SAndroid Build Coastguard Worker 
2442*f6dc9357SAndroid Build Coastguard Worker   UInt32 sum = g_BenchCpuFreqTemp;
2443*f6dc9357SAndroid Build Coastguard Worker   for (UInt64 k = p->NumIterations; k > 0; k--)
2444*f6dc9357SAndroid Build Coastguard Worker   {
2445*f6dc9357SAndroid Build Coastguard Worker     if (p->Callback)
2446*f6dc9357SAndroid Build Coastguard Worker     {
2447*f6dc9357SAndroid Build Coastguard Worker       p->CallbackRes = p->Callback->CheckBreak();
2448*f6dc9357SAndroid Build Coastguard Worker       if (p->CallbackRes != S_OK)
2449*f6dc9357SAndroid Build Coastguard Worker         break;
2450*f6dc9357SAndroid Build Coastguard Worker     }
2451*f6dc9357SAndroid Build Coastguard Worker     sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp);
2452*f6dc9357SAndroid Build Coastguard Worker   }
2453*f6dc9357SAndroid Build Coastguard Worker   p->ValRes = sum;
2454*f6dc9357SAndroid Build Coastguard Worker   return THREAD_FUNC_RET_ZERO;
2455*f6dc9357SAndroid Build Coastguard Worker }
2456*f6dc9357SAndroid Build Coastguard Worker 
2457*f6dc9357SAndroid Build Coastguard Worker struct CFreqThreads
2458*f6dc9357SAndroid Build Coastguard Worker {
2459*f6dc9357SAndroid Build Coastguard Worker   CFreqInfo *Items;
2460*f6dc9357SAndroid Build Coastguard Worker   UInt32 NumThreads;
2461*f6dc9357SAndroid Build Coastguard Worker 
2462*f6dc9357SAndroid Build Coastguard Worker   CFreqThreads(): Items(NULL), NumThreads(0) {}
2463*f6dc9357SAndroid Build Coastguard Worker 
2464*f6dc9357SAndroid Build Coastguard Worker   WRes WaitAll()
2465*f6dc9357SAndroid Build Coastguard Worker   {
2466*f6dc9357SAndroid Build Coastguard Worker     WRes wres = 0;
2467*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < NumThreads; i++)
2468*f6dc9357SAndroid Build Coastguard Worker     {
2469*f6dc9357SAndroid Build Coastguard Worker       WRes wres2 = Items[i].Wait_If_Created();
2470*f6dc9357SAndroid Build Coastguard Worker       if (wres == 0 && wres2 != 0)
2471*f6dc9357SAndroid Build Coastguard Worker         wres = wres2;
2472*f6dc9357SAndroid Build Coastguard Worker     }
2473*f6dc9357SAndroid Build Coastguard Worker     NumThreads = 0;
2474*f6dc9357SAndroid Build Coastguard Worker     return wres;
2475*f6dc9357SAndroid Build Coastguard Worker   }
2476*f6dc9357SAndroid Build Coastguard Worker 
2477*f6dc9357SAndroid Build Coastguard Worker   ~CFreqThreads()
2478*f6dc9357SAndroid Build Coastguard Worker   {
2479*f6dc9357SAndroid Build Coastguard Worker     WaitAll();
2480*f6dc9357SAndroid Build Coastguard Worker     delete []Items;
2481*f6dc9357SAndroid Build Coastguard Worker   }
2482*f6dc9357SAndroid Build Coastguard Worker };
2483*f6dc9357SAndroid Build Coastguard Worker 
2484*f6dc9357SAndroid Build Coastguard Worker 
2485*f6dc9357SAndroid Build Coastguard Worker static THREAD_FUNC_DECL CrcThreadFunction(void *param);
2486*f6dc9357SAndroid Build Coastguard Worker 
2487*f6dc9357SAndroid Build Coastguard Worker struct CCrcInfo: public CBaseThreadInfo
2488*f6dc9357SAndroid Build Coastguard Worker {
2489*f6dc9357SAndroid Build Coastguard Worker   const Byte *Data;
2490*f6dc9357SAndroid Build Coastguard Worker   size_t Size;
2491*f6dc9357SAndroid Build Coastguard Worker   UInt64 NumIterations;
2492*f6dc9357SAndroid Build Coastguard Worker   bool CheckSumDefined;
2493*f6dc9357SAndroid Build Coastguard Worker   UInt32 CheckSum;
2494*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IHasher> Hasher;
2495*f6dc9357SAndroid Build Coastguard Worker   HRESULT Res;
2496*f6dc9357SAndroid Build Coastguard Worker   UInt32 CheckSum_Res;
2497*f6dc9357SAndroid Build Coastguard Worker 
2498*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
2499*f6dc9357SAndroid Build Coastguard Worker   NSynchronization::CManualResetEvent ReadyEvent;
2500*f6dc9357SAndroid Build Coastguard Worker   UInt32 ThreadIndex;
2501*f6dc9357SAndroid Build Coastguard Worker   CBenchSyncCommon *Common;
2502*f6dc9357SAndroid Build Coastguard Worker   CAffinityMode AffinityMode;
2503*f6dc9357SAndroid Build Coastguard Worker   #endif
2504*f6dc9357SAndroid Build Coastguard Worker 
2505*f6dc9357SAndroid Build Coastguard Worker   // we want to call CCrcInfo_Base::Buffer.Free() in main thread.
2506*f6dc9357SAndroid Build Coastguard Worker   // so we uses non-local CCrcInfo_Base.
2507*f6dc9357SAndroid Build Coastguard Worker   CCrcInfo_Base crcib;
2508*f6dc9357SAndroid Build Coastguard Worker 
2509*f6dc9357SAndroid Build Coastguard Worker   HRESULT CreateThread()
2510*f6dc9357SAndroid Build Coastguard Worker   {
2511*f6dc9357SAndroid Build Coastguard Worker     WRes res = 0;
2512*f6dc9357SAndroid Build Coastguard Worker     if (!ReadyEvent.IsCreated())
2513*f6dc9357SAndroid Build Coastguard Worker       res = ReadyEvent.Create();
2514*f6dc9357SAndroid Build Coastguard Worker     if (res == 0)
2515*f6dc9357SAndroid Build Coastguard Worker       res = AffinityMode.CreateThread_WithAffinity(Thread, CrcThreadFunction, this,
2516*f6dc9357SAndroid Build Coastguard Worker           ThreadIndex);
2517*f6dc9357SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(res);
2518*f6dc9357SAndroid Build Coastguard Worker   }
2519*f6dc9357SAndroid Build Coastguard Worker 
2520*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_ALLOCA
2521*f6dc9357SAndroid Build Coastguard Worker   size_t AllocaSize;
2522*f6dc9357SAndroid Build Coastguard Worker   #endif
2523*f6dc9357SAndroid Build Coastguard Worker 
2524*f6dc9357SAndroid Build Coastguard Worker   void Process();
2525*f6dc9357SAndroid Build Coastguard Worker 
2526*f6dc9357SAndroid Build Coastguard Worker   CCrcInfo(): Res(E_FAIL) {}
2527*f6dc9357SAndroid Build Coastguard Worker };
2528*f6dc9357SAndroid Build Coastguard Worker 
2529*f6dc9357SAndroid Build Coastguard Worker static const bool k_Crc_CreateLocalBuf_For_File = true; // for total BW test
2530*f6dc9357SAndroid Build Coastguard Worker // static const bool k_Crc_CreateLocalBuf_For_File = false; // for shared memory read test
2531*f6dc9357SAndroid Build Coastguard Worker 
2532*f6dc9357SAndroid Build Coastguard Worker void CCrcInfo::Process()
2533*f6dc9357SAndroid Build Coastguard Worker {
2534*f6dc9357SAndroid Build Coastguard Worker   crcib.CreateLocalBuf = k_Crc_CreateLocalBuf_For_File;
2535*f6dc9357SAndroid Build Coastguard Worker   // we can use additional Generate() passes to reduce some time effects for new page allocation
2536*f6dc9357SAndroid Build Coastguard Worker   // for (unsigned y = 0; y < 10; y++)
2537*f6dc9357SAndroid Build Coastguard Worker   Res = crcib.Generate(Data, Size);
2538*f6dc9357SAndroid Build Coastguard Worker 
2539*f6dc9357SAndroid Build Coastguard Worker   // if (Common)
2540*f6dc9357SAndroid Build Coastguard Worker   {
2541*f6dc9357SAndroid Build Coastguard Worker     WRes wres = ReadyEvent.Set();
2542*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
2543*f6dc9357SAndroid Build Coastguard Worker     {
2544*f6dc9357SAndroid Build Coastguard Worker       if (Res == 0)
2545*f6dc9357SAndroid Build Coastguard Worker         Res = HRESULT_FROM_WIN32(wres);
2546*f6dc9357SAndroid Build Coastguard Worker       return;
2547*f6dc9357SAndroid Build Coastguard Worker     }
2548*f6dc9357SAndroid Build Coastguard Worker     if (Res != 0)
2549*f6dc9357SAndroid Build Coastguard Worker       return;
2550*f6dc9357SAndroid Build Coastguard Worker 
2551*f6dc9357SAndroid Build Coastguard Worker     wres = Common->StartEvent.Lock();
2552*f6dc9357SAndroid Build Coastguard Worker 
2553*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
2554*f6dc9357SAndroid Build Coastguard Worker     {
2555*f6dc9357SAndroid Build Coastguard Worker       Res = HRESULT_FROM_WIN32(wres);
2556*f6dc9357SAndroid Build Coastguard Worker       return;
2557*f6dc9357SAndroid Build Coastguard Worker     }
2558*f6dc9357SAndroid Build Coastguard Worker     if (Common->ExitMode)
2559*f6dc9357SAndroid Build Coastguard Worker       return;
2560*f6dc9357SAndroid Build Coastguard Worker   }
2561*f6dc9357SAndroid Build Coastguard Worker 
2562*f6dc9357SAndroid Build Coastguard Worker   Res = crcib.CrcProcess(NumIterations,
2563*f6dc9357SAndroid Build Coastguard Worker       CheckSumDefined ? &CheckSum : NULL, Hasher,
2564*f6dc9357SAndroid Build Coastguard Worker       Callback);
2565*f6dc9357SAndroid Build Coastguard Worker   CheckSum_Res = crcib.CheckSum_Res;
2566*f6dc9357SAndroid Build Coastguard Worker   /*
2567*f6dc9357SAndroid Build Coastguard Worker   We don't want to include the time of slow CCrcInfo_Base::Buffer.Free()
2568*f6dc9357SAndroid Build Coastguard Worker   to time of benchmark. So we don't free Buffer here
2569*f6dc9357SAndroid Build Coastguard Worker   */
2570*f6dc9357SAndroid Build Coastguard Worker   // crcib.Buffer.Free();
2571*f6dc9357SAndroid Build Coastguard Worker }
2572*f6dc9357SAndroid Build Coastguard Worker 
2573*f6dc9357SAndroid Build Coastguard Worker 
2574*f6dc9357SAndroid Build Coastguard Worker static THREAD_FUNC_DECL CrcThreadFunction(void *param)
2575*f6dc9357SAndroid Build Coastguard Worker {
2576*f6dc9357SAndroid Build Coastguard Worker   CCrcInfo *p = (CCrcInfo *)param;
2577*f6dc9357SAndroid Build Coastguard Worker 
2578*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_ALLOCA
2579*f6dc9357SAndroid Build Coastguard Worker   alloca(p->AllocaSize);
2580*f6dc9357SAndroid Build Coastguard Worker   #endif
2581*f6dc9357SAndroid Build Coastguard Worker   p->Process();
2582*f6dc9357SAndroid Build Coastguard Worker   return THREAD_FUNC_RET_ZERO;
2583*f6dc9357SAndroid Build Coastguard Worker }
2584*f6dc9357SAndroid Build Coastguard Worker 
2585*f6dc9357SAndroid Build Coastguard Worker 
2586*f6dc9357SAndroid Build Coastguard Worker struct CCrcThreads
2587*f6dc9357SAndroid Build Coastguard Worker {
2588*f6dc9357SAndroid Build Coastguard Worker   CCrcInfo *Items;
2589*f6dc9357SAndroid Build Coastguard Worker   unsigned NumThreads;
2590*f6dc9357SAndroid Build Coastguard Worker   CBenchSyncCommon Common;
2591*f6dc9357SAndroid Build Coastguard Worker   bool NeedClose;
2592*f6dc9357SAndroid Build Coastguard Worker 
2593*f6dc9357SAndroid Build Coastguard Worker   CCrcThreads(): Items(NULL), NumThreads(0), NeedClose(false) {}
2594*f6dc9357SAndroid Build Coastguard Worker 
2595*f6dc9357SAndroid Build Coastguard Worker   WRes StartAndWait(bool exitMode = false);
2596*f6dc9357SAndroid Build Coastguard Worker 
2597*f6dc9357SAndroid Build Coastguard Worker   ~CCrcThreads()
2598*f6dc9357SAndroid Build Coastguard Worker   {
2599*f6dc9357SAndroid Build Coastguard Worker     StartAndWait(true);
2600*f6dc9357SAndroid Build Coastguard Worker     delete []Items;
2601*f6dc9357SAndroid Build Coastguard Worker   }
2602*f6dc9357SAndroid Build Coastguard Worker };
2603*f6dc9357SAndroid Build Coastguard Worker 
2604*f6dc9357SAndroid Build Coastguard Worker 
2605*f6dc9357SAndroid Build Coastguard Worker WRes CCrcThreads::StartAndWait(bool exitMode)
2606*f6dc9357SAndroid Build Coastguard Worker {
2607*f6dc9357SAndroid Build Coastguard Worker   if (!NeedClose)
2608*f6dc9357SAndroid Build Coastguard Worker     return 0;
2609*f6dc9357SAndroid Build Coastguard Worker 
2610*f6dc9357SAndroid Build Coastguard Worker   Common.ExitMode = exitMode;
2611*f6dc9357SAndroid Build Coastguard Worker   WRes wres = Common.StartEvent.Set();
2612*f6dc9357SAndroid Build Coastguard Worker 
2613*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumThreads; i++)
2614*f6dc9357SAndroid Build Coastguard Worker   {
2615*f6dc9357SAndroid Build Coastguard Worker     WRes wres2 = Items[i].Wait_If_Created();
2616*f6dc9357SAndroid Build Coastguard Worker     if (wres == 0 && wres2 != 0)
2617*f6dc9357SAndroid Build Coastguard Worker       wres = wres2;
2618*f6dc9357SAndroid Build Coastguard Worker   }
2619*f6dc9357SAndroid Build Coastguard Worker   NumThreads = 0;
2620*f6dc9357SAndroid Build Coastguard Worker   NeedClose = false;
2621*f6dc9357SAndroid Build Coastguard Worker   return wres;
2622*f6dc9357SAndroid Build Coastguard Worker }
2623*f6dc9357SAndroid Build Coastguard Worker 
2624*f6dc9357SAndroid Build Coastguard Worker #endif
2625*f6dc9357SAndroid Build Coastguard Worker 
2626*f6dc9357SAndroid Build Coastguard Worker 
2627*f6dc9357SAndroid Build Coastguard Worker /*
2628*f6dc9357SAndroid Build Coastguard Worker static UInt32 CrcCalc1(const Byte *buf, size_t size)
2629*f6dc9357SAndroid Build Coastguard Worker {
2630*f6dc9357SAndroid Build Coastguard Worker   UInt32 crc = CRC_INIT_VAL;
2631*f6dc9357SAndroid Build Coastguard Worker   for (size_t i = 0; i < size; i++)
2632*f6dc9357SAndroid Build Coastguard Worker     crc = CRC_UPDATE_BYTE(crc, buf[i]);
2633*f6dc9357SAndroid Build Coastguard Worker   return CRC_GET_DIGEST(crc);
2634*f6dc9357SAndroid Build Coastguard Worker }
2635*f6dc9357SAndroid Build Coastguard Worker */
2636*f6dc9357SAndroid Build Coastguard Worker 
2637*f6dc9357SAndroid Build Coastguard Worker /*
2638*f6dc9357SAndroid Build Coastguard Worker static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG)
2639*f6dc9357SAndroid Build Coastguard Worker {
2640*f6dc9357SAndroid Build Coastguard Worker   RandGen(buf, size, RG);
2641*f6dc9357SAndroid Build Coastguard Worker   return CrcCalc1(buf, size);
2642*f6dc9357SAndroid Build Coastguard Worker }
2643*f6dc9357SAndroid Build Coastguard Worker */
2644*f6dc9357SAndroid Build Coastguard Worker 
2645*f6dc9357SAndroid Build Coastguard Worker static bool CrcInternalTest()
2646*f6dc9357SAndroid Build Coastguard Worker {
2647*f6dc9357SAndroid Build Coastguard Worker   CAlignedBuffer buffer;
2648*f6dc9357SAndroid Build Coastguard Worker   const size_t kBufSize = 1 << 11;
2649*f6dc9357SAndroid Build Coastguard Worker   const size_t kCheckSize = 1 << 6;
2650*f6dc9357SAndroid Build Coastguard Worker   buffer.Alloc(kBufSize);
2651*f6dc9357SAndroid Build Coastguard Worker   if (!buffer.IsAllocated())
2652*f6dc9357SAndroid Build Coastguard Worker     return false;
2653*f6dc9357SAndroid Build Coastguard Worker   Byte *buf = (Byte *)buffer;
2654*f6dc9357SAndroid Build Coastguard Worker   RandGen_BufAfterPad(buf, kBufSize);
2655*f6dc9357SAndroid Build Coastguard Worker   UInt32 sum = 0;
2656*f6dc9357SAndroid Build Coastguard Worker   for (size_t i = 0; i < kBufSize - kCheckSize * 2; i += kCheckSize - 1)
2657*f6dc9357SAndroid Build Coastguard Worker     for (size_t j = 0; j < kCheckSize; j++)
2658*f6dc9357SAndroid Build Coastguard Worker     {
2659*f6dc9357SAndroid Build Coastguard Worker       sum = rotlFixed(sum, 11);
2660*f6dc9357SAndroid Build Coastguard Worker       sum += CrcCalc(buf + i + j, j);
2661*f6dc9357SAndroid Build Coastguard Worker     }
2662*f6dc9357SAndroid Build Coastguard Worker   return sum == 0x28462c7c;
2663*f6dc9357SAndroid Build Coastguard Worker }
2664*f6dc9357SAndroid Build Coastguard Worker 
2665*f6dc9357SAndroid Build Coastguard Worker struct CBenchMethod
2666*f6dc9357SAndroid Build Coastguard Worker {
2667*f6dc9357SAndroid Build Coastguard Worker   unsigned Weight;
2668*f6dc9357SAndroid Build Coastguard Worker   unsigned DictBits;
2669*f6dc9357SAndroid Build Coastguard Worker   Int32 EncComplex;
2670*f6dc9357SAndroid Build Coastguard Worker   Int32 DecComplexCompr;
2671*f6dc9357SAndroid Build Coastguard Worker   Int32 DecComplexUnc;
2672*f6dc9357SAndroid Build Coastguard Worker   const char *Name;
2673*f6dc9357SAndroid Build Coastguard Worker   // unsigned KeySize;
2674*f6dc9357SAndroid Build Coastguard Worker };
2675*f6dc9357SAndroid Build Coastguard Worker 
2676*f6dc9357SAndroid Build Coastguard Worker // #define USE_SW_CMPLX
2677*f6dc9357SAndroid Build Coastguard Worker 
2678*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_SW_CMPLX
2679*f6dc9357SAndroid Build Coastguard Worker #define CMPLX(x) ((x) * 1000)
2680*f6dc9357SAndroid Build Coastguard Worker #else
2681*f6dc9357SAndroid Build Coastguard Worker #define CMPLX(x) (x)
2682*f6dc9357SAndroid Build Coastguard Worker #endif
2683*f6dc9357SAndroid Build Coastguard Worker 
2684*f6dc9357SAndroid Build Coastguard Worker static const CBenchMethod g_Bench[] =
2685*f6dc9357SAndroid Build Coastguard Worker {
2686*f6dc9357SAndroid Build Coastguard Worker   // { 40, 17,  357,  145,   20, "LZMA:x1" },
2687*f6dc9357SAndroid Build Coastguard Worker   // { 20, 18,  360,  145,   20, "LZMA2:x1:mt2" },
2688*f6dc9357SAndroid Build Coastguard Worker 
2689*f6dc9357SAndroid Build Coastguard Worker   { 20, 18,  360,  145,   20, "LZMA:x1" },
2690*f6dc9357SAndroid Build Coastguard Worker   { 20, 22,  600,  145,   20, "LZMA:x3" },
2691*f6dc9357SAndroid Build Coastguard Worker 
2692*f6dc9357SAndroid Build Coastguard Worker   { 80, 24, 1220,  145,   20, "LZMA:x5:mt1" },
2693*f6dc9357SAndroid Build Coastguard Worker   { 80, 24, 1220,  145,   20, "LZMA:x5:mt2" },
2694*f6dc9357SAndroid Build Coastguard Worker 
2695*f6dc9357SAndroid Build Coastguard Worker   { 10, 16,  124,   40,   14, "Deflate:x1" },
2696*f6dc9357SAndroid Build Coastguard Worker   { 20, 16,  376,   40,   14, "Deflate:x5" },
2697*f6dc9357SAndroid Build Coastguard Worker   { 10, 16, 1082,   40,   14, "Deflate:x7" },
2698*f6dc9357SAndroid Build Coastguard Worker   { 10, 17,  422,   40,   14, "Deflate64:x5" },
2699*f6dc9357SAndroid Build Coastguard Worker 
2700*f6dc9357SAndroid Build Coastguard Worker   { 10, 15,  590,   69,   69, "BZip2:x1" },
2701*f6dc9357SAndroid Build Coastguard Worker   { 20, 19,  815,  122,  122, "BZip2:x5" },
2702*f6dc9357SAndroid Build Coastguard Worker   { 10, 19,  815,  122,  122, "BZip2:x5:mt2" },
2703*f6dc9357SAndroid Build Coastguard Worker   { 10, 19, 2530,  122,  122, "BZip2:x7" },
2704*f6dc9357SAndroid Build Coastguard Worker 
2705*f6dc9357SAndroid Build Coastguard Worker   // { 10, 18, 1010,    0, 1150, "PPMDZip:x1" },
2706*f6dc9357SAndroid Build Coastguard Worker   { 10, 18, 1010,    0, 1150, "PPMD:x1" },
2707*f6dc9357SAndroid Build Coastguard Worker   // { 10, 22, 1655,    0, 1830, "PPMDZip:x5" },
2708*f6dc9357SAndroid Build Coastguard Worker   { 10, 22, 1655,    0, 1830, "PPMD:x5" },
2709*f6dc9357SAndroid Build Coastguard Worker 
2710*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,  -16,    0,  -16, "Swap2" },
2711*f6dc9357SAndroid Build Coastguard Worker   {  2,  0,  -16,    0,  -16, "Swap4" },
2712*f6dc9357SAndroid Build Coastguard Worker 
2713*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,    3,    0,    4, "Delta:1" },
2714*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,    3,    0,    4, "Delta:2" },
2715*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,    3,    0,    4, "Delta:3" },
2716*f6dc9357SAndroid Build Coastguard Worker   {  2,  0,    3,    0,    4, "Delta:4" },
2717*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,    3,    0,    4, "Delta:8" },
2718*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0,    3,    0,    4, "Delta:32" },
2719*f6dc9357SAndroid Build Coastguard Worker 
2720*f6dc9357SAndroid Build Coastguard Worker   {  2,  0,    2,    0,    2, "BCJ" },
2721*f6dc9357SAndroid Build Coastguard Worker   {  2,  0,    1,    0,    1, "ARM64" },
2722*f6dc9357SAndroid Build Coastguard Worker   {  2,  0,    1,    0,    1, "RISCV" },
2723*f6dc9357SAndroid Build Coastguard Worker 
2724*f6dc9357SAndroid Build Coastguard Worker   // { 10,  0,   18,    0,   18, "AES128CBC:1" },
2725*f6dc9357SAndroid Build Coastguard Worker   // { 10,  0,   21,    0,   21, "AES192CBC:1" },
2726*f6dc9357SAndroid Build Coastguard Worker   { 10,  0,   24,    0,   24, "AES256CBC:1" },
2727*f6dc9357SAndroid Build Coastguard Worker 
2728*f6dc9357SAndroid Build Coastguard Worker   // { 10,  0,   18,    0,   18, "AES128CTR:1" },
2729*f6dc9357SAndroid Build Coastguard Worker   // { 10,  0,   21,    0,   21, "AES192CTR:1" },
2730*f6dc9357SAndroid Build Coastguard Worker   // { 10,  0,   24,    0,   24, "AES256CTR:1" },
2731*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0, CMPLX(6), 0, CMPLX(1), "AES128CBC:2" },
2732*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0, CMPLX(7), 0, CMPLX(1), "AES192CBC:2" },
2733*f6dc9357SAndroid Build Coastguard Worker   {  2,  0, CMPLX(8), 0, CMPLX(1), "AES256CBC:2" },
2734*f6dc9357SAndroid Build Coastguard Worker 
2735*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES128CTR:2" },
2736*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" },
2737*f6dc9357SAndroid Build Coastguard Worker   // {  2,  0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" },
2738*f6dc9357SAndroid Build Coastguard Worker 
2739*f6dc9357SAndroid Build Coastguard Worker   // {  1,  0, CMPLX(6), 0, -2, "AES128CBC:3" },
2740*f6dc9357SAndroid Build Coastguard Worker   // {  1,  0, CMPLX(7), 0, -2, "AES192CBC:3" },
2741*f6dc9357SAndroid Build Coastguard Worker   {  1,  0, CMPLX(8), 0, -2, "AES256CBC:3" }
2742*f6dc9357SAndroid Build Coastguard Worker 
2743*f6dc9357SAndroid Build Coastguard Worker   // {  1,  0, CMPLX(1), 0, -2, "AES128CTR:3" },
2744*f6dc9357SAndroid Build Coastguard Worker   // {  1,  0, CMPLX(1), 0, -2, "AES192CTR:3" },
2745*f6dc9357SAndroid Build Coastguard Worker   // {  1,  0, CMPLX(1), 0, -2, "AES256CTR:3" },
2746*f6dc9357SAndroid Build Coastguard Worker };
2747*f6dc9357SAndroid Build Coastguard Worker 
2748*f6dc9357SAndroid Build Coastguard Worker struct CBenchHash
2749*f6dc9357SAndroid Build Coastguard Worker {
2750*f6dc9357SAndroid Build Coastguard Worker   unsigned Weight;
2751*f6dc9357SAndroid Build Coastguard Worker   UInt32 Complex;
2752*f6dc9357SAndroid Build Coastguard Worker   UInt32 CheckSum;
2753*f6dc9357SAndroid Build Coastguard Worker   const char *Name;
2754*f6dc9357SAndroid Build Coastguard Worker };
2755*f6dc9357SAndroid Build Coastguard Worker 
2756*f6dc9357SAndroid Build Coastguard Worker // #define ARM_CRC_MUL 100
2757*f6dc9357SAndroid Build Coastguard Worker #define ARM_CRC_MUL 1
2758*f6dc9357SAndroid Build Coastguard Worker 
2759*f6dc9357SAndroid Build Coastguard Worker #define k_Hash_Complex_Mult 256
2760*f6dc9357SAndroid Build Coastguard Worker 
2761*f6dc9357SAndroid Build Coastguard Worker static const CBenchHash g_Hash[] =
2762*f6dc9357SAndroid Build Coastguard Worker {
2763*f6dc9357SAndroid Build Coastguard Worker   { 20,   256, 0x21e207bb, "CRC32:12" } ,
2764*f6dc9357SAndroid Build Coastguard Worker   {  2,   128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
2765*f6dc9357SAndroid Build Coastguard Worker   {  2,    64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
2766*f6dc9357SAndroid Build Coastguard Worker   { 10,   256, 0x41b901d1, "CRC64" },
2767*f6dc9357SAndroid Build Coastguard Worker   {  5,    64, 0x43eac94f, "XXH64" },
2768*f6dc9357SAndroid Build Coastguard Worker   {  2,  2340, 0x3398a904, "MD5" },
2769*f6dc9357SAndroid Build Coastguard Worker   { 10,  2340,                       0xff769021, "SHA1:1" },
2770*f6dc9357SAndroid Build Coastguard Worker   {  2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
2771*f6dc9357SAndroid Build Coastguard Worker   { 10,  5100,                       0x7913ba03, "SHA256:1" },
2772*f6dc9357SAndroid Build Coastguard Worker   {  2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
2773*f6dc9357SAndroid Build Coastguard Worker   {  5,  3200,                       0xe7aeb394, "SHA512:1" },
2774*f6dc9357SAndroid Build Coastguard Worker   {  2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" },
2775*f6dc9357SAndroid Build Coastguard Worker   // { 10, 3428,       0x1cc99b18, "SHAKE128" },
2776*f6dc9357SAndroid Build Coastguard Worker   // { 10, 4235,       0x74eaddc3, "SHAKE256" },
2777*f6dc9357SAndroid Build Coastguard Worker   // { 10, 4000,       0xdf3e6863, "SHA3-224" },
2778*f6dc9357SAndroid Build Coastguard Worker   {  5, 4200,       0xcecac10d, "SHA3-256" },
2779*f6dc9357SAndroid Build Coastguard Worker   // { 10, 5538,       0x4e5d9163, "SHA3-384" },
2780*f6dc9357SAndroid Build Coastguard Worker   // { 10, 8000,       0x96a58289, "SHA3-512" },
2781*f6dc9357SAndroid Build Coastguard Worker   {  2,  4096, 0x85189d02, "BLAKE2sp:1" },
2782*f6dc9357SAndroid Build Coastguard Worker   {  2,  1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast
2783*f6dc9357SAndroid Build Coastguard Worker   {  2,   512, 0x85189d02, "BLAKE2sp:3" }  // avx2-way8-fast
2784*f6dc9357SAndroid Build Coastguard Worker #if 0
2785*f6dc9357SAndroid Build Coastguard Worker   , {  2,  2048, 0x85189d02, "BLAKE2sp:4" } // sse2-way1
2786*f6dc9357SAndroid Build Coastguard Worker   , {  2,  1024, 0x85189d02, "BLAKE2sp:5" } // sse2-way2
2787*f6dc9357SAndroid Build Coastguard Worker   , {  2,  1024, 0x85189d02, "BLAKE2sp:6" } // avx2-way2
2788*f6dc9357SAndroid Build Coastguard Worker   , {  2,  1024, 0x85189d02, "BLAKE2sp:7" } // avx2-way4
2789*f6dc9357SAndroid Build Coastguard Worker #endif
2790*f6dc9357SAndroid Build Coastguard Worker };
2791*f6dc9357SAndroid Build Coastguard Worker 
2792*f6dc9357SAndroid Build Coastguard Worker static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size)
2793*f6dc9357SAndroid Build Coastguard Worker {
2794*f6dc9357SAndroid Build Coastguard Worker   char s[128];
2795*f6dc9357SAndroid Build Coastguard Worker   unsigned startPos = (unsigned)sizeof(s) - 32;
2796*f6dc9357SAndroid Build Coastguard Worker   memset(s, ' ', startPos);
2797*f6dc9357SAndroid Build Coastguard Worker   ConvertUInt64ToString(value, s + startPos);
2798*f6dc9357SAndroid Build Coastguard Worker   // if (withSpace)
2799*f6dc9357SAndroid Build Coastguard Worker   {
2800*f6dc9357SAndroid Build Coastguard Worker     startPos--;
2801*f6dc9357SAndroid Build Coastguard Worker     size++;
2802*f6dc9357SAndroid Build Coastguard Worker   }
2803*f6dc9357SAndroid Build Coastguard Worker   unsigned len = (unsigned)strlen(s + startPos);
2804*f6dc9357SAndroid Build Coastguard Worker   if (size > len)
2805*f6dc9357SAndroid Build Coastguard Worker   {
2806*f6dc9357SAndroid Build Coastguard Worker     size -= len;
2807*f6dc9357SAndroid Build Coastguard Worker     if (startPos < size)
2808*f6dc9357SAndroid Build Coastguard Worker       startPos = 0;
2809*f6dc9357SAndroid Build Coastguard Worker     else
2810*f6dc9357SAndroid Build Coastguard Worker       startPos -= size;
2811*f6dc9357SAndroid Build Coastguard Worker   }
2812*f6dc9357SAndroid Build Coastguard Worker   f.Print(s + startPos);
2813*f6dc9357SAndroid Build Coastguard Worker }
2814*f6dc9357SAndroid Build Coastguard Worker 
2815*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_Name = 12;
2816*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_SmallName = 4;
2817*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_Speed = 9;
2818*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_Usage = 5;
2819*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_RU = 6;
2820*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_Rating = 6;
2821*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_EU = 5;
2822*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_Effec = 5;
2823*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_CrcSpeed = 8;
2824*f6dc9357SAndroid Build Coastguard Worker 
2825*f6dc9357SAndroid Build Coastguard Worker 
2826*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating;
2827*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec;
2828*f6dc9357SAndroid Build Coastguard Worker 
2829*f6dc9357SAndroid Build Coastguard Worker 
2830*f6dc9357SAndroid Build Coastguard Worker static void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size)
2831*f6dc9357SAndroid Build Coastguard Worker {
2832*f6dc9357SAndroid Build Coastguard Worker   PrintNumber(f, (rating + 500000) / 1000000, size);
2833*f6dc9357SAndroid Build Coastguard Worker }
2834*f6dc9357SAndroid Build Coastguard Worker 
2835*f6dc9357SAndroid Build Coastguard Worker 
2836*f6dc9357SAndroid Build Coastguard Worker static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size)
2837*f6dc9357SAndroid Build Coastguard Worker {
2838*f6dc9357SAndroid Build Coastguard Worker   UInt64 v = 0;
2839*f6dc9357SAndroid Build Coastguard Worker   if (divider != 0)
2840*f6dc9357SAndroid Build Coastguard Worker     v = (val * 100 + divider / 2) / divider;
2841*f6dc9357SAndroid Build Coastguard Worker   PrintNumber(f, v, size);
2842*f6dc9357SAndroid Build Coastguard Worker }
2843*f6dc9357SAndroid Build Coastguard Worker 
2844*f6dc9357SAndroid Build Coastguard Worker static void PrintChars(IBenchPrintCallback &f, char c, unsigned size)
2845*f6dc9357SAndroid Build Coastguard Worker {
2846*f6dc9357SAndroid Build Coastguard Worker   char s[256];
2847*f6dc9357SAndroid Build Coastguard Worker   memset(s, (Byte)c, size);
2848*f6dc9357SAndroid Build Coastguard Worker   s[size] = 0;
2849*f6dc9357SAndroid Build Coastguard Worker   f.Print(s);
2850*f6dc9357SAndroid Build Coastguard Worker }
2851*f6dc9357SAndroid Build Coastguard Worker 
2852*f6dc9357SAndroid Build Coastguard Worker static void PrintSpaces(IBenchPrintCallback &f, unsigned size)
2853*f6dc9357SAndroid Build Coastguard Worker {
2854*f6dc9357SAndroid Build Coastguard Worker   PrintChars(f, ' ', size);
2855*f6dc9357SAndroid Build Coastguard Worker }
2856*f6dc9357SAndroid Build Coastguard Worker 
2857*f6dc9357SAndroid Build Coastguard Worker static void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size)
2858*f6dc9357SAndroid Build Coastguard Worker {
2859*f6dc9357SAndroid Build Coastguard Worker   PrintNumber(f, Benchmark_GetUsage_Percents(usage), size);
2860*f6dc9357SAndroid Build Coastguard Worker }
2861*f6dc9357SAndroid Build Coastguard Worker 
2862*f6dc9357SAndroid Build Coastguard Worker static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq)
2863*f6dc9357SAndroid Build Coastguard Worker {
2864*f6dc9357SAndroid Build Coastguard Worker   PrintUsage(f, usage, kFieldSize_Usage);
2865*f6dc9357SAndroid Build Coastguard Worker   PrintRating(f, rpu, kFieldSize_RU);
2866*f6dc9357SAndroid Build Coastguard Worker   PrintRating(f, rating, kFieldSize_Rating);
2867*f6dc9357SAndroid Build Coastguard Worker   if (showFreq)
2868*f6dc9357SAndroid Build Coastguard Worker   {
2869*f6dc9357SAndroid Build Coastguard Worker     if (cpuFreq == 0)
2870*f6dc9357SAndroid Build Coastguard Worker       PrintSpaces(f, kFieldSize_EUAndEffec);
2871*f6dc9357SAndroid Build Coastguard Worker     else
2872*f6dc9357SAndroid Build Coastguard Worker     {
2873*f6dc9357SAndroid Build Coastguard Worker       PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU);
2874*f6dc9357SAndroid Build Coastguard Worker       PrintPercents(f, rating, cpuFreq, kFieldSize_Effec);
2875*f6dc9357SAndroid Build Coastguard Worker     }
2876*f6dc9357SAndroid Build Coastguard Worker   }
2877*f6dc9357SAndroid Build Coastguard Worker }
2878*f6dc9357SAndroid Build Coastguard Worker 
2879*f6dc9357SAndroid Build Coastguard Worker 
2880*f6dc9357SAndroid Build Coastguard Worker void CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info)
2881*f6dc9357SAndroid Build Coastguard Worker {
2882*f6dc9357SAndroid Build Coastguard Worker   Speed = info.GetUnpackSizeSpeed();
2883*f6dc9357SAndroid Build Coastguard Worker   Usage = info.GetUsage();
2884*f6dc9357SAndroid Build Coastguard Worker   RPU = info.GetRatingPerUsage(Rating);
2885*f6dc9357SAndroid Build Coastguard Worker }
2886*f6dc9357SAndroid Build Coastguard Worker 
2887*f6dc9357SAndroid Build Coastguard Worker void CTotalBenchRes::Mult_For_Weight(unsigned weight)
2888*f6dc9357SAndroid Build Coastguard Worker {
2889*f6dc9357SAndroid Build Coastguard Worker   NumIterations2 *= weight;
2890*f6dc9357SAndroid Build Coastguard Worker   RPU *= weight;
2891*f6dc9357SAndroid Build Coastguard Worker   Rating *= weight;
2892*f6dc9357SAndroid Build Coastguard Worker   Usage *= weight;
2893*f6dc9357SAndroid Build Coastguard Worker   Speed *= weight;
2894*f6dc9357SAndroid Build Coastguard Worker }
2895*f6dc9357SAndroid Build Coastguard Worker 
2896*f6dc9357SAndroid Build Coastguard Worker void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r)
2897*f6dc9357SAndroid Build Coastguard Worker {
2898*f6dc9357SAndroid Build Coastguard Worker   Rating += r.Rating;
2899*f6dc9357SAndroid Build Coastguard Worker   Usage += r.Usage;
2900*f6dc9357SAndroid Build Coastguard Worker   RPU += r.RPU;
2901*f6dc9357SAndroid Build Coastguard Worker   Speed += r.Speed;
2902*f6dc9357SAndroid Build Coastguard Worker     // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
2903*f6dc9357SAndroid Build Coastguard Worker   NumIterations2 += r.NumIterations2;
2904*f6dc9357SAndroid Build Coastguard Worker }
2905*f6dc9357SAndroid Build Coastguard Worker 
2906*f6dc9357SAndroid Build Coastguard Worker static void PrintResults(IBenchPrintCallback *f,
2907*f6dc9357SAndroid Build Coastguard Worker     const CBenchInfo &info,
2908*f6dc9357SAndroid Build Coastguard Worker     unsigned weight,
2909*f6dc9357SAndroid Build Coastguard Worker     UInt64 rating,
2910*f6dc9357SAndroid Build Coastguard Worker     bool showFreq, UInt64 cpuFreq,
2911*f6dc9357SAndroid Build Coastguard Worker     CTotalBenchRes *res)
2912*f6dc9357SAndroid Build Coastguard Worker {
2913*f6dc9357SAndroid Build Coastguard Worker   CTotalBenchRes t;
2914*f6dc9357SAndroid Build Coastguard Worker   t.Rating = rating;
2915*f6dc9357SAndroid Build Coastguard Worker   t.NumIterations2 = 1;
2916*f6dc9357SAndroid Build Coastguard Worker   t.Generate_From_BenchInfo(info);
2917*f6dc9357SAndroid Build Coastguard Worker 
2918*f6dc9357SAndroid Build Coastguard Worker   if (f)
2919*f6dc9357SAndroid Build Coastguard Worker   {
2920*f6dc9357SAndroid Build Coastguard Worker     if (t.Speed != 0)
2921*f6dc9357SAndroid Build Coastguard Worker       PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed);
2922*f6dc9357SAndroid Build Coastguard Worker     else
2923*f6dc9357SAndroid Build Coastguard Worker       PrintSpaces(*f, 1 + kFieldSize_Speed);
2924*f6dc9357SAndroid Build Coastguard Worker   }
2925*f6dc9357SAndroid Build Coastguard Worker   if (f)
2926*f6dc9357SAndroid Build Coastguard Worker   {
2927*f6dc9357SAndroid Build Coastguard Worker     PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq);
2928*f6dc9357SAndroid Build Coastguard Worker   }
2929*f6dc9357SAndroid Build Coastguard Worker 
2930*f6dc9357SAndroid Build Coastguard Worker   if (res)
2931*f6dc9357SAndroid Build Coastguard Worker   {
2932*f6dc9357SAndroid Build Coastguard Worker     // res->NumIterations1++;
2933*f6dc9357SAndroid Build Coastguard Worker     t.Mult_For_Weight(weight);
2934*f6dc9357SAndroid Build Coastguard Worker     res->Update_With_Res(t);
2935*f6dc9357SAndroid Build Coastguard Worker   }
2936*f6dc9357SAndroid Build Coastguard Worker }
2937*f6dc9357SAndroid Build Coastguard Worker 
2938*f6dc9357SAndroid Build Coastguard Worker static void PrintTotals(IBenchPrintCallback &f,
2939*f6dc9357SAndroid Build Coastguard Worker     bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res)
2940*f6dc9357SAndroid Build Coastguard Worker {
2941*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1;
2942*f6dc9357SAndroid Build Coastguard Worker   const UInt64 speed = res.Speed / numIterations2;
2943*f6dc9357SAndroid Build Coastguard Worker   if (showSpeed && speed != 0)
2944*f6dc9357SAndroid Build Coastguard Worker     PrintNumber(f, speed / 1024, kFieldSize_Speed);
2945*f6dc9357SAndroid Build Coastguard Worker   else
2946*f6dc9357SAndroid Build Coastguard Worker     PrintSpaces(f, 1 + kFieldSize_Speed);
2947*f6dc9357SAndroid Build Coastguard Worker 
2948*f6dc9357SAndroid Build Coastguard Worker   // PrintSpaces(f, 1 + kFieldSize_Speed);
2949*f6dc9357SAndroid Build Coastguard Worker   // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1;
2950*f6dc9357SAndroid Build Coastguard Worker   PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
2951*f6dc9357SAndroid Build Coastguard Worker }
2952*f6dc9357SAndroid Build Coastguard Worker 
2953*f6dc9357SAndroid Build Coastguard Worker 
2954*f6dc9357SAndroid Build Coastguard Worker static void PrintHex(AString &s, UInt64 v)
2955*f6dc9357SAndroid Build Coastguard Worker {
2956*f6dc9357SAndroid Build Coastguard Worker   char temp[32];
2957*f6dc9357SAndroid Build Coastguard Worker   ConvertUInt64ToHex(v, temp);
2958*f6dc9357SAndroid Build Coastguard Worker   s += temp;
2959*f6dc9357SAndroid Build Coastguard Worker }
2960*f6dc9357SAndroid Build Coastguard Worker 
2961*f6dc9357SAndroid Build Coastguard Worker AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
2962*f6dc9357SAndroid Build Coastguard Worker {
2963*f6dc9357SAndroid Build Coastguard Worker   AString s;
2964*f6dc9357SAndroid Build Coastguard Worker   // s.Add_UInt32(ti.numProcessThreads);
2965*f6dc9357SAndroid Build Coastguard Worker   unsigned numSysThreads = ti.GetNumSystemThreads();
2966*f6dc9357SAndroid Build Coastguard Worker   if (ti.GetNumProcessThreads() != numSysThreads)
2967*f6dc9357SAndroid Build Coastguard Worker   {
2968*f6dc9357SAndroid Build Coastguard Worker     // if (ti.numProcessThreads != ti.numSysThreads)
2969*f6dc9357SAndroid Build Coastguard Worker     {
2970*f6dc9357SAndroid Build Coastguard Worker       s += " / ";
2971*f6dc9357SAndroid Build Coastguard Worker       s.Add_UInt32(numSysThreads);
2972*f6dc9357SAndroid Build Coastguard Worker     }
2973*f6dc9357SAndroid Build Coastguard Worker     s += " : ";
2974*f6dc9357SAndroid Build Coastguard Worker     #ifdef _WIN32
2975*f6dc9357SAndroid Build Coastguard Worker     PrintHex(s, ti.processAffinityMask);
2976*f6dc9357SAndroid Build Coastguard Worker     s += " / ";
2977*f6dc9357SAndroid Build Coastguard Worker     PrintHex(s, ti.systemAffinityMask);
2978*f6dc9357SAndroid Build Coastguard Worker     #else
2979*f6dc9357SAndroid Build Coastguard Worker     unsigned i = (numSysThreads + 3) & ~(unsigned)3;
2980*f6dc9357SAndroid Build Coastguard Worker     if (i == 0)
2981*f6dc9357SAndroid Build Coastguard Worker       i = 4;
2982*f6dc9357SAndroid Build Coastguard Worker     for (; i >= 4; )
2983*f6dc9357SAndroid Build Coastguard Worker     {
2984*f6dc9357SAndroid Build Coastguard Worker       i -= 4;
2985*f6dc9357SAndroid Build Coastguard Worker       unsigned val = 0;
2986*f6dc9357SAndroid Build Coastguard Worker       for (unsigned k = 0; k < 4; k++)
2987*f6dc9357SAndroid Build Coastguard Worker       {
2988*f6dc9357SAndroid Build Coastguard Worker         const unsigned bit = (ti.IsCpuSet(i + k) ? 1 : 0);
2989*f6dc9357SAndroid Build Coastguard Worker         val += (bit << k);
2990*f6dc9357SAndroid Build Coastguard Worker       }
2991*f6dc9357SAndroid Build Coastguard Worker       PrintHex(s, val);
2992*f6dc9357SAndroid Build Coastguard Worker     }
2993*f6dc9357SAndroid Build Coastguard Worker     #endif
2994*f6dc9357SAndroid Build Coastguard Worker   }
2995*f6dc9357SAndroid Build Coastguard Worker   return s;
2996*f6dc9357SAndroid Build Coastguard Worker }
2997*f6dc9357SAndroid Build Coastguard Worker 
2998*f6dc9357SAndroid Build Coastguard Worker 
2999*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LARGE_PAGES
3000*f6dc9357SAndroid Build Coastguard Worker 
3001*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
3002*f6dc9357SAndroid Build Coastguard Worker extern bool g_LargePagesMode;
3003*f6dc9357SAndroid Build Coastguard Worker extern "C"
3004*f6dc9357SAndroid Build Coastguard Worker {
3005*f6dc9357SAndroid Build Coastguard Worker   extern SIZE_T g_LargePageSize;
3006*f6dc9357SAndroid Build Coastguard Worker }
3007*f6dc9357SAndroid Build Coastguard Worker #endif
3008*f6dc9357SAndroid Build Coastguard Worker 
3009*f6dc9357SAndroid Build Coastguard Worker void Add_LargePages_String(AString &s)
3010*f6dc9357SAndroid Build Coastguard Worker {
3011*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
3012*f6dc9357SAndroid Build Coastguard Worker   if (g_LargePagesMode || g_LargePageSize != 0)
3013*f6dc9357SAndroid Build Coastguard Worker   {
3014*f6dc9357SAndroid Build Coastguard Worker     s.Add_OptSpaced("(LP-");
3015*f6dc9357SAndroid Build Coastguard Worker     PrintSize_KMGT_Or_Hex(s, g_LargePageSize);
3016*f6dc9357SAndroid Build Coastguard Worker     #ifdef MY_CPU_X86_OR_AMD64
3017*f6dc9357SAndroid Build Coastguard Worker     if (CPU_IsSupported_PageGB())
3018*f6dc9357SAndroid Build Coastguard Worker       s += "-1G";
3019*f6dc9357SAndroid Build Coastguard Worker     #endif
3020*f6dc9357SAndroid Build Coastguard Worker     if (!g_LargePagesMode)
3021*f6dc9357SAndroid Build Coastguard Worker       s += "-NA";
3022*f6dc9357SAndroid Build Coastguard Worker     s += ")";
3023*f6dc9357SAndroid Build Coastguard Worker   }
3024*f6dc9357SAndroid Build Coastguard Worker   #else
3025*f6dc9357SAndroid Build Coastguard Worker     s += "";
3026*f6dc9357SAndroid Build Coastguard Worker   #endif
3027*f6dc9357SAndroid Build Coastguard Worker }
3028*f6dc9357SAndroid Build Coastguard Worker 
3029*f6dc9357SAndroid Build Coastguard Worker #endif
3030*f6dc9357SAndroid Build Coastguard Worker 
3031*f6dc9357SAndroid Build Coastguard Worker 
3032*f6dc9357SAndroid Build Coastguard Worker 
3033*f6dc9357SAndroid Build Coastguard Worker static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
3034*f6dc9357SAndroid Build Coastguard Worker     bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
3035*f6dc9357SAndroid Build Coastguard Worker {
3036*f6dc9357SAndroid Build Coastguard Worker   f.Print("RAM ");
3037*f6dc9357SAndroid Build Coastguard Worker   f.Print(sizeString);
3038*f6dc9357SAndroid Build Coastguard Worker   if (size_Defined)
3039*f6dc9357SAndroid Build Coastguard Worker     PrintNumber(f, (size >> 20), 6);
3040*f6dc9357SAndroid Build Coastguard Worker   else
3041*f6dc9357SAndroid Build Coastguard Worker     f.Print("      ?");
3042*f6dc9357SAndroid Build Coastguard Worker   f.Print(" MB");
3043*f6dc9357SAndroid Build Coastguard Worker 
3044*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_LARGE_PAGES
3045*f6dc9357SAndroid Build Coastguard Worker   {
3046*f6dc9357SAndroid Build Coastguard Worker     AString s;
3047*f6dc9357SAndroid Build Coastguard Worker     Add_LargePages_String(s);
3048*f6dc9357SAndroid Build Coastguard Worker     f.Print(s);
3049*f6dc9357SAndroid Build Coastguard Worker   }
3050*f6dc9357SAndroid Build Coastguard Worker   #endif
3051*f6dc9357SAndroid Build Coastguard Worker 
3052*f6dc9357SAndroid Build Coastguard Worker   f.Print(",  # ");
3053*f6dc9357SAndroid Build Coastguard Worker   f.Print(threadsString);
3054*f6dc9357SAndroid Build Coastguard Worker   PrintNumber(f, numThreads, 3);
3055*f6dc9357SAndroid Build Coastguard Worker }
3056*f6dc9357SAndroid Build Coastguard Worker 
3057*f6dc9357SAndroid Build Coastguard Worker 
3058*f6dc9357SAndroid Build Coastguard Worker 
3059*f6dc9357SAndroid Build Coastguard Worker struct CBenchCallbackToPrint Z7_final: public IBenchCallback
3060*f6dc9357SAndroid Build Coastguard Worker {
3061*f6dc9357SAndroid Build Coastguard Worker   bool NeedPrint;
3062*f6dc9357SAndroid Build Coastguard Worker   bool Use2Columns;
3063*f6dc9357SAndroid Build Coastguard Worker   bool ShowFreq;
3064*f6dc9357SAndroid Build Coastguard Worker   unsigned NameFieldSize;
3065*f6dc9357SAndroid Build Coastguard Worker 
3066*f6dc9357SAndroid Build Coastguard Worker   unsigned EncodeWeight;
3067*f6dc9357SAndroid Build Coastguard Worker   unsigned DecodeWeight;
3068*f6dc9357SAndroid Build Coastguard Worker 
3069*f6dc9357SAndroid Build Coastguard Worker   UInt64 CpuFreq;
3070*f6dc9357SAndroid Build Coastguard Worker   UInt64 DictSize;
3071*f6dc9357SAndroid Build Coastguard Worker 
3072*f6dc9357SAndroid Build Coastguard Worker   IBenchPrintCallback *_file;
3073*f6dc9357SAndroid Build Coastguard Worker   CBenchProps BenchProps;
3074*f6dc9357SAndroid Build Coastguard Worker   CTotalBenchRes EncodeRes;
3075*f6dc9357SAndroid Build Coastguard Worker   CTotalBenchRes DecodeRes;
3076*f6dc9357SAndroid Build Coastguard Worker 
3077*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo BenchInfo_Results[2];
3078*f6dc9357SAndroid Build Coastguard Worker 
3079*f6dc9357SAndroid Build Coastguard Worker   CBenchCallbackToPrint():
3080*f6dc9357SAndroid Build Coastguard Worker       NeedPrint(true),
3081*f6dc9357SAndroid Build Coastguard Worker       Use2Columns(false),
3082*f6dc9357SAndroid Build Coastguard Worker       ShowFreq(false),
3083*f6dc9357SAndroid Build Coastguard Worker       NameFieldSize(0),
3084*f6dc9357SAndroid Build Coastguard Worker       EncodeWeight(1),
3085*f6dc9357SAndroid Build Coastguard Worker       DecodeWeight(1),
3086*f6dc9357SAndroid Build Coastguard Worker       CpuFreq(0)
3087*f6dc9357SAndroid Build Coastguard Worker       {}
3088*f6dc9357SAndroid Build Coastguard Worker 
3089*f6dc9357SAndroid Build Coastguard Worker   void Init() { EncodeRes.Init(); DecodeRes.Init(); }
3090*f6dc9357SAndroid Build Coastguard Worker   void Print(const char *s);
3091*f6dc9357SAndroid Build Coastguard Worker   void NewLine();
3092*f6dc9357SAndroid Build Coastguard Worker 
3093*f6dc9357SAndroid Build Coastguard Worker   HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
3094*f6dc9357SAndroid Build Coastguard Worker   HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override;
3095*f6dc9357SAndroid Build Coastguard Worker   HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override;
3096*f6dc9357SAndroid Build Coastguard Worker };
3097*f6dc9357SAndroid Build Coastguard Worker 
3098*f6dc9357SAndroid Build Coastguard Worker HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
3099*f6dc9357SAndroid Build Coastguard Worker {
3100*f6dc9357SAndroid Build Coastguard Worker   ShowFreq = showFreq;
3101*f6dc9357SAndroid Build Coastguard Worker   CpuFreq = cpuFreq;
3102*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3103*f6dc9357SAndroid Build Coastguard Worker }
3104*f6dc9357SAndroid Build Coastguard Worker 
3105*f6dc9357SAndroid Build Coastguard Worker HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
3106*f6dc9357SAndroid Build Coastguard Worker {
3107*f6dc9357SAndroid Build Coastguard Worker   RINOK(_file->CheckBreak())
3108*f6dc9357SAndroid Build Coastguard Worker   if (final)
3109*f6dc9357SAndroid Build Coastguard Worker     BenchInfo_Results[0] = info;
3110*f6dc9357SAndroid Build Coastguard Worker   if (final)
3111*f6dc9357SAndroid Build Coastguard Worker   if (NeedPrint)
3112*f6dc9357SAndroid Build Coastguard Worker   {
3113*f6dc9357SAndroid Build Coastguard Worker     const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
3114*f6dc9357SAndroid Build Coastguard Worker     PrintResults(_file, info,
3115*f6dc9357SAndroid Build Coastguard Worker         EncodeWeight, rating,
3116*f6dc9357SAndroid Build Coastguard Worker         ShowFreq, CpuFreq, &EncodeRes);
3117*f6dc9357SAndroid Build Coastguard Worker     if (!Use2Columns)
3118*f6dc9357SAndroid Build Coastguard Worker       _file->NewLine();
3119*f6dc9357SAndroid Build Coastguard Worker   }
3120*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3121*f6dc9357SAndroid Build Coastguard Worker }
3122*f6dc9357SAndroid Build Coastguard Worker 
3123*f6dc9357SAndroid Build Coastguard Worker static const char * const kSep = "  | ";
3124*f6dc9357SAndroid Build Coastguard Worker 
3125*f6dc9357SAndroid Build Coastguard Worker HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
3126*f6dc9357SAndroid Build Coastguard Worker {
3127*f6dc9357SAndroid Build Coastguard Worker   RINOK(_file->CheckBreak())
3128*f6dc9357SAndroid Build Coastguard Worker   if (final)
3129*f6dc9357SAndroid Build Coastguard Worker     BenchInfo_Results[1] = info;
3130*f6dc9357SAndroid Build Coastguard Worker   if (final)
3131*f6dc9357SAndroid Build Coastguard Worker   if (NeedPrint)
3132*f6dc9357SAndroid Build Coastguard Worker   {
3133*f6dc9357SAndroid Build Coastguard Worker     const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
3134*f6dc9357SAndroid Build Coastguard Worker     if (Use2Columns)
3135*f6dc9357SAndroid Build Coastguard Worker       _file->Print(kSep);
3136*f6dc9357SAndroid Build Coastguard Worker     else
3137*f6dc9357SAndroid Build Coastguard Worker       PrintSpaces(*_file, NameFieldSize);
3138*f6dc9357SAndroid Build Coastguard Worker     CBenchInfo info2 = info;
3139*f6dc9357SAndroid Build Coastguard Worker     info2.UnpackSize *= info2.NumIterations;
3140*f6dc9357SAndroid Build Coastguard Worker     info2.PackSize *= info2.NumIterations;
3141*f6dc9357SAndroid Build Coastguard Worker     info2.NumIterations = 1;
3142*f6dc9357SAndroid Build Coastguard Worker     PrintResults(_file, info2,
3143*f6dc9357SAndroid Build Coastguard Worker         DecodeWeight, rating,
3144*f6dc9357SAndroid Build Coastguard Worker         ShowFreq, CpuFreq, &DecodeRes);
3145*f6dc9357SAndroid Build Coastguard Worker   }
3146*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3147*f6dc9357SAndroid Build Coastguard Worker }
3148*f6dc9357SAndroid Build Coastguard Worker 
3149*f6dc9357SAndroid Build Coastguard Worker void CBenchCallbackToPrint::Print(const char *s)
3150*f6dc9357SAndroid Build Coastguard Worker {
3151*f6dc9357SAndroid Build Coastguard Worker   _file->Print(s);
3152*f6dc9357SAndroid Build Coastguard Worker }
3153*f6dc9357SAndroid Build Coastguard Worker 
3154*f6dc9357SAndroid Build Coastguard Worker void CBenchCallbackToPrint::NewLine()
3155*f6dc9357SAndroid Build Coastguard Worker {
3156*f6dc9357SAndroid Build Coastguard Worker   _file->NewLine();
3157*f6dc9357SAndroid Build Coastguard Worker }
3158*f6dc9357SAndroid Build Coastguard Worker 
3159*f6dc9357SAndroid Build Coastguard Worker static void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
3160*f6dc9357SAndroid Build Coastguard Worker {
3161*f6dc9357SAndroid Build Coastguard Worker   f.Print(s);
3162*f6dc9357SAndroid Build Coastguard Worker   int numSpaces = (int)size - (int)MyStringLen(s);
3163*f6dc9357SAndroid Build Coastguard Worker   if (numSpaces > 0)
3164*f6dc9357SAndroid Build Coastguard Worker     PrintSpaces(f, (unsigned)numSpaces);
3165*f6dc9357SAndroid Build Coastguard Worker }
3166*f6dc9357SAndroid Build Coastguard Worker 
3167*f6dc9357SAndroid Build Coastguard Worker static void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
3168*f6dc9357SAndroid Build Coastguard Worker {
3169*f6dc9357SAndroid Build Coastguard Worker   int numSpaces = (int)size - (int)MyStringLen(s);
3170*f6dc9357SAndroid Build Coastguard Worker   if (numSpaces > 0)
3171*f6dc9357SAndroid Build Coastguard Worker     PrintSpaces(f, (unsigned)numSpaces);
3172*f6dc9357SAndroid Build Coastguard Worker   f.Print(s);
3173*f6dc9357SAndroid Build Coastguard Worker }
3174*f6dc9357SAndroid Build Coastguard Worker 
3175*f6dc9357SAndroid Build Coastguard Worker 
3176*f6dc9357SAndroid Build Coastguard Worker static bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name)
3177*f6dc9357SAndroid Build Coastguard Worker {
3178*f6dc9357SAndroid Build Coastguard Worker   UString wildc = GetUnicodeString(mask);
3179*f6dc9357SAndroid Build Coastguard Worker   UString bname = GetUnicodeString(name);
3180*f6dc9357SAndroid Build Coastguard Worker   wildc.MakeLower_Ascii();
3181*f6dc9357SAndroid Build Coastguard Worker   bname.MakeLower_Ascii();
3182*f6dc9357SAndroid Build Coastguard Worker   return DoesWildcardMatchName(wildc, bname);
3183*f6dc9357SAndroid Build Coastguard Worker }
3184*f6dc9357SAndroid Build Coastguard Worker 
3185*f6dc9357SAndroid Build Coastguard Worker 
3186*f6dc9357SAndroid Build Coastguard Worker static HRESULT TotalBench(
3187*f6dc9357SAndroid Build Coastguard Worker     DECL_EXTERNAL_CODECS_LOC_VARS
3188*f6dc9357SAndroid Build Coastguard Worker     const COneMethodInfo &methodMask,
3189*f6dc9357SAndroid Build Coastguard Worker     UInt64 complexInCommands,
3190*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
3191*f6dc9357SAndroid Build Coastguard Worker     UInt32 numThreads,
3192*f6dc9357SAndroid Build Coastguard Worker     const CAffinityMode *affinityMode,
3193*f6dc9357SAndroid Build Coastguard Worker   #endif
3194*f6dc9357SAndroid Build Coastguard Worker     bool forceUnpackSize,
3195*f6dc9357SAndroid Build Coastguard Worker     size_t unpackSize,
3196*f6dc9357SAndroid Build Coastguard Worker     const Byte *fileData,
3197*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
3198*f6dc9357SAndroid Build Coastguard Worker {
3199*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
3200*f6dc9357SAndroid Build Coastguard Worker   {
3201*f6dc9357SAndroid Build Coastguard Worker     const CBenchMethod &bench = g_Bench[i];
3202*f6dc9357SAndroid Build Coastguard Worker     if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
3203*f6dc9357SAndroid Build Coastguard Worker       continue;
3204*f6dc9357SAndroid Build Coastguard Worker     PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
3205*f6dc9357SAndroid Build Coastguard Worker     {
3206*f6dc9357SAndroid Build Coastguard Worker       unsigned keySize = 32;
3207*f6dc9357SAndroid Build Coastguard Worker            if (IsString1PrefixedByString2(bench.Name, "AES128")) keySize = 16;
3208*f6dc9357SAndroid Build Coastguard Worker       else if (IsString1PrefixedByString2(bench.Name, "AES192")) keySize = 24;
3209*f6dc9357SAndroid Build Coastguard Worker       callback->BenchProps.KeySize = keySize;
3210*f6dc9357SAndroid Build Coastguard Worker     }
3211*f6dc9357SAndroid Build Coastguard Worker     callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
3212*f6dc9357SAndroid Build Coastguard Worker     callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
3213*f6dc9357SAndroid Build Coastguard Worker     callback->BenchProps.EncComplex = bench.EncComplex;
3214*f6dc9357SAndroid Build Coastguard Worker 
3215*f6dc9357SAndroid Build Coastguard Worker     COneMethodInfo method;
3216*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant propVariant;
3217*f6dc9357SAndroid Build Coastguard Worker     propVariant = bench.Name;
3218*f6dc9357SAndroid Build Coastguard Worker     RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
3219*f6dc9357SAndroid Build Coastguard Worker 
3220*f6dc9357SAndroid Build Coastguard Worker     size_t unpackSize2 = unpackSize;
3221*f6dc9357SAndroid Build Coastguard Worker     if (!forceUnpackSize && bench.DictBits == 0)
3222*f6dc9357SAndroid Build Coastguard Worker       unpackSize2 = kFilterUnpackSize;
3223*f6dc9357SAndroid Build Coastguard Worker 
3224*f6dc9357SAndroid Build Coastguard Worker     callback->EncodeWeight = bench.Weight;
3225*f6dc9357SAndroid Build Coastguard Worker     callback->DecodeWeight = bench.Weight;
3226*f6dc9357SAndroid Build Coastguard Worker 
3227*f6dc9357SAndroid Build Coastguard Worker     const HRESULT res = MethodBench(
3228*f6dc9357SAndroid Build Coastguard Worker         EXTERNAL_CODECS_LOC_VARS
3229*f6dc9357SAndroid Build Coastguard Worker         complexInCommands,
3230*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
3231*f6dc9357SAndroid Build Coastguard Worker         false, numThreads, affinityMode,
3232*f6dc9357SAndroid Build Coastguard Worker         #endif
3233*f6dc9357SAndroid Build Coastguard Worker         method,
3234*f6dc9357SAndroid Build Coastguard Worker         unpackSize2, fileData,
3235*f6dc9357SAndroid Build Coastguard Worker         bench.DictBits,
3236*f6dc9357SAndroid Build Coastguard Worker         printCallback, callback, &callback->BenchProps);
3237*f6dc9357SAndroid Build Coastguard Worker 
3238*f6dc9357SAndroid Build Coastguard Worker     if (res == E_NOTIMPL)
3239*f6dc9357SAndroid Build Coastguard Worker     {
3240*f6dc9357SAndroid Build Coastguard Worker       // callback->Print(" ---");
3241*f6dc9357SAndroid Build Coastguard Worker       // we need additional empty line as line for decompression results
3242*f6dc9357SAndroid Build Coastguard Worker       if (!callback->Use2Columns)
3243*f6dc9357SAndroid Build Coastguard Worker         callback->NewLine();
3244*f6dc9357SAndroid Build Coastguard Worker     }
3245*f6dc9357SAndroid Build Coastguard Worker     else
3246*f6dc9357SAndroid Build Coastguard Worker     {
3247*f6dc9357SAndroid Build Coastguard Worker       RINOK(res)
3248*f6dc9357SAndroid Build Coastguard Worker     }
3249*f6dc9357SAndroid Build Coastguard Worker 
3250*f6dc9357SAndroid Build Coastguard Worker     callback->NewLine();
3251*f6dc9357SAndroid Build Coastguard Worker   }
3252*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3253*f6dc9357SAndroid Build Coastguard Worker }
3254*f6dc9357SAndroid Build Coastguard Worker 
3255*f6dc9357SAndroid Build Coastguard Worker 
3256*f6dc9357SAndroid Build Coastguard Worker struct CFreqBench
3257*f6dc9357SAndroid Build Coastguard Worker {
3258*f6dc9357SAndroid Build Coastguard Worker   // in:
3259*f6dc9357SAndroid Build Coastguard Worker   UInt64 complexInCommands;
3260*f6dc9357SAndroid Build Coastguard Worker   UInt32 numThreads;
3261*f6dc9357SAndroid Build Coastguard Worker   bool showFreq;
3262*f6dc9357SAndroid Build Coastguard Worker   UInt64 specifiedFreq;
3263*f6dc9357SAndroid Build Coastguard Worker 
3264*f6dc9357SAndroid Build Coastguard Worker   // out:
3265*f6dc9357SAndroid Build Coastguard Worker   UInt64 CpuFreqRes;
3266*f6dc9357SAndroid Build Coastguard Worker   UInt64 UsageRes;
3267*f6dc9357SAndroid Build Coastguard Worker   UInt32 res;
3268*f6dc9357SAndroid Build Coastguard Worker 
3269*f6dc9357SAndroid Build Coastguard Worker   CFreqBench()
3270*f6dc9357SAndroid Build Coastguard Worker     {}
3271*f6dc9357SAndroid Build Coastguard Worker 
3272*f6dc9357SAndroid Build Coastguard Worker   HRESULT FreqBench(IBenchPrintCallback *_file
3273*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
3274*f6dc9357SAndroid Build Coastguard Worker       , const CAffinityMode *affinityMode
3275*f6dc9357SAndroid Build Coastguard Worker       #endif
3276*f6dc9357SAndroid Build Coastguard Worker       );
3277*f6dc9357SAndroid Build Coastguard Worker };
3278*f6dc9357SAndroid Build Coastguard Worker 
3279*f6dc9357SAndroid Build Coastguard Worker 
3280*f6dc9357SAndroid Build Coastguard Worker HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file
3281*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
3282*f6dc9357SAndroid Build Coastguard Worker     , const CAffinityMode *affinityMode
3283*f6dc9357SAndroid Build Coastguard Worker     #endif
3284*f6dc9357SAndroid Build Coastguard Worker     )
3285*f6dc9357SAndroid Build Coastguard Worker {
3286*f6dc9357SAndroid Build Coastguard Worker   res = 0;
3287*f6dc9357SAndroid Build Coastguard Worker   CpuFreqRes = 0;
3288*f6dc9357SAndroid Build Coastguard Worker   UsageRes = 0;
3289*f6dc9357SAndroid Build Coastguard Worker 
3290*f6dc9357SAndroid Build Coastguard Worker   if (numThreads == 0)
3291*f6dc9357SAndroid Build Coastguard Worker     numThreads = 1;
3292*f6dc9357SAndroid Build Coastguard Worker 
3293*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_ST
3294*f6dc9357SAndroid Build Coastguard Worker   numThreads = 1;
3295*f6dc9357SAndroid Build Coastguard Worker   #endif
3296*f6dc9357SAndroid Build Coastguard Worker 
3297*f6dc9357SAndroid Build Coastguard Worker   const UInt32 complexity = kNumFreqCommands;
3298*f6dc9357SAndroid Build Coastguard Worker   UInt64 numIterations = complexInCommands / complexity;
3299*f6dc9357SAndroid Build Coastguard Worker   UInt32 numIterations2 = 1 << 30;
3300*f6dc9357SAndroid Build Coastguard Worker   if (numIterations > numIterations2)
3301*f6dc9357SAndroid Build Coastguard Worker     numIterations /= numIterations2;
3302*f6dc9357SAndroid Build Coastguard Worker   else
3303*f6dc9357SAndroid Build Coastguard Worker   {
3304*f6dc9357SAndroid Build Coastguard Worker     numIterations2 = (UInt32)numIterations;
3305*f6dc9357SAndroid Build Coastguard Worker     numIterations = 1;
3306*f6dc9357SAndroid Build Coastguard Worker   }
3307*f6dc9357SAndroid Build Coastguard Worker 
3308*f6dc9357SAndroid Build Coastguard Worker   CBenchInfoCalc progressInfoSpec;
3309*f6dc9357SAndroid Build Coastguard Worker 
3310*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
3311*f6dc9357SAndroid Build Coastguard Worker 
3312*f6dc9357SAndroid Build Coastguard Worker   bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity();
3313*f6dc9357SAndroid Build Coastguard Worker 
3314*f6dc9357SAndroid Build Coastguard Worker   if (mtMode)
3315*f6dc9357SAndroid Build Coastguard Worker   {
3316*f6dc9357SAndroid Build Coastguard Worker     CFreqThreads threads;
3317*f6dc9357SAndroid Build Coastguard Worker     threads.Items = new CFreqInfo[numThreads];
3318*f6dc9357SAndroid Build Coastguard Worker     UInt32 i;
3319*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3320*f6dc9357SAndroid Build Coastguard Worker     {
3321*f6dc9357SAndroid Build Coastguard Worker       CFreqInfo &info = threads.Items[i];
3322*f6dc9357SAndroid Build Coastguard Worker       info.Callback = _file;
3323*f6dc9357SAndroid Build Coastguard Worker       info.CallbackRes = S_OK;
3324*f6dc9357SAndroid Build Coastguard Worker       info.NumIterations = numIterations;
3325*f6dc9357SAndroid Build Coastguard Worker       info.Size = numIterations2;
3326*f6dc9357SAndroid Build Coastguard Worker     }
3327*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetStartTime();
3328*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3329*f6dc9357SAndroid Build Coastguard Worker     {
3330*f6dc9357SAndroid Build Coastguard Worker       // Sleep(10);
3331*f6dc9357SAndroid Build Coastguard Worker       CFreqInfo &info = threads.Items[i];
3332*f6dc9357SAndroid Build Coastguard Worker       WRes wres = affinityMode->CreateThread_WithAffinity(info.Thread, FreqThreadFunction, &info, i);
3333*f6dc9357SAndroid Build Coastguard Worker       if (info.Thread.IsCreated())
3334*f6dc9357SAndroid Build Coastguard Worker         threads.NumThreads++;
3335*f6dc9357SAndroid Build Coastguard Worker       if (wres != 0)
3336*f6dc9357SAndroid Build Coastguard Worker         return HRESULT_FROM_WIN32(wres);
3337*f6dc9357SAndroid Build Coastguard Worker     }
3338*f6dc9357SAndroid Build Coastguard Worker     WRes wres = threads.WaitAll();
3339*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
3340*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
3341*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3342*f6dc9357SAndroid Build Coastguard Worker     {
3343*f6dc9357SAndroid Build Coastguard Worker       RINOK(threads.Items[i].CallbackRes)
3344*f6dc9357SAndroid Build Coastguard Worker     }
3345*f6dc9357SAndroid Build Coastguard Worker   }
3346*f6dc9357SAndroid Build Coastguard Worker   else
3347*f6dc9357SAndroid Build Coastguard Worker   #endif
3348*f6dc9357SAndroid Build Coastguard Worker   {
3349*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetStartTime();
3350*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum = g_BenchCpuFreqTemp;
3351*f6dc9357SAndroid Build Coastguard Worker     UInt64 k = numIterations;
3352*f6dc9357SAndroid Build Coastguard Worker     do
3353*f6dc9357SAndroid Build Coastguard Worker     {
3354*f6dc9357SAndroid Build Coastguard Worker       sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp);
3355*f6dc9357SAndroid Build Coastguard Worker       if (_file)
3356*f6dc9357SAndroid Build Coastguard Worker       {
3357*f6dc9357SAndroid Build Coastguard Worker         RINOK(_file->CheckBreak())
3358*f6dc9357SAndroid Build Coastguard Worker       }
3359*f6dc9357SAndroid Build Coastguard Worker     }
3360*f6dc9357SAndroid Build Coastguard Worker     while (--k);
3361*f6dc9357SAndroid Build Coastguard Worker     res += sum;
3362*f6dc9357SAndroid Build Coastguard Worker   }
3363*f6dc9357SAndroid Build Coastguard Worker 
3364*f6dc9357SAndroid Build Coastguard Worker   if (res == 0x12345678)
3365*f6dc9357SAndroid Build Coastguard Worker   if (_file)
3366*f6dc9357SAndroid Build Coastguard Worker   {
3367*f6dc9357SAndroid Build Coastguard Worker     RINOK(_file->CheckBreak())
3368*f6dc9357SAndroid Build Coastguard Worker   }
3369*f6dc9357SAndroid Build Coastguard Worker 
3370*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo info;
3371*f6dc9357SAndroid Build Coastguard Worker   progressInfoSpec.SetFinishTime(info);
3372*f6dc9357SAndroid Build Coastguard Worker 
3373*f6dc9357SAndroid Build Coastguard Worker   info.UnpackSize = 0;
3374*f6dc9357SAndroid Build Coastguard Worker   info.PackSize = 0;
3375*f6dc9357SAndroid Build Coastguard Worker   info.NumIterations = 1;
3376*f6dc9357SAndroid Build Coastguard Worker 
3377*f6dc9357SAndroid Build Coastguard Worker   const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity;
3378*f6dc9357SAndroid Build Coastguard Worker   const UInt64 rating = info.GetSpeed(numCommands);
3379*f6dc9357SAndroid Build Coastguard Worker   CpuFreqRes = rating / numThreads;
3380*f6dc9357SAndroid Build Coastguard Worker   UsageRes = info.GetUsage();
3381*f6dc9357SAndroid Build Coastguard Worker 
3382*f6dc9357SAndroid Build Coastguard Worker   if (_file)
3383*f6dc9357SAndroid Build Coastguard Worker   {
3384*f6dc9357SAndroid Build Coastguard Worker     PrintResults(_file, info,
3385*f6dc9357SAndroid Build Coastguard Worker           0, // weight
3386*f6dc9357SAndroid Build Coastguard Worker           rating,
3387*f6dc9357SAndroid Build Coastguard Worker           showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL);
3388*f6dc9357SAndroid Build Coastguard Worker     RINOK(_file->CheckBreak())
3389*f6dc9357SAndroid Build Coastguard Worker   }
3390*f6dc9357SAndroid Build Coastguard Worker 
3391*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3392*f6dc9357SAndroid Build Coastguard Worker }
3393*f6dc9357SAndroid Build Coastguard Worker 
3394*f6dc9357SAndroid Build Coastguard Worker 
3395*f6dc9357SAndroid Build Coastguard Worker 
3396*f6dc9357SAndroid Build Coastguard Worker static HRESULT CrcBench(
3397*f6dc9357SAndroid Build Coastguard Worker     DECL_EXTERNAL_CODECS_LOC_VARS
3398*f6dc9357SAndroid Build Coastguard Worker     UInt64 complexInCommands,
3399*f6dc9357SAndroid Build Coastguard Worker     UInt32 numThreads,
3400*f6dc9357SAndroid Build Coastguard Worker     const size_t bufferSize,
3401*f6dc9357SAndroid Build Coastguard Worker     const Byte *fileData,
3402*f6dc9357SAndroid Build Coastguard Worker 
3403*f6dc9357SAndroid Build Coastguard Worker     UInt64 &speed,
3404*f6dc9357SAndroid Build Coastguard Worker     UInt64 &usage,
3405*f6dc9357SAndroid Build Coastguard Worker 
3406*f6dc9357SAndroid Build Coastguard Worker     UInt32 complexity, unsigned benchWeight,
3407*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *checkSum,
3408*f6dc9357SAndroid Build Coastguard Worker     const COneMethodInfo &method,
3409*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *_file,
3410*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
3411*f6dc9357SAndroid Build Coastguard Worker     const CAffinityMode *affinityMode,
3412*f6dc9357SAndroid Build Coastguard Worker     #endif
3413*f6dc9357SAndroid Build Coastguard Worker     bool showRating,
3414*f6dc9357SAndroid Build Coastguard Worker     CTotalBenchRes *encodeRes,
3415*f6dc9357SAndroid Build Coastguard Worker     bool showFreq, UInt64 cpuFreq)
3416*f6dc9357SAndroid Build Coastguard Worker {
3417*f6dc9357SAndroid Build Coastguard Worker   if (numThreads == 0)
3418*f6dc9357SAndroid Build Coastguard Worker     numThreads = 1;
3419*f6dc9357SAndroid Build Coastguard Worker 
3420*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_ST
3421*f6dc9357SAndroid Build Coastguard Worker   numThreads = 1;
3422*f6dc9357SAndroid Build Coastguard Worker   #endif
3423*f6dc9357SAndroid Build Coastguard Worker 
3424*f6dc9357SAndroid Build Coastguard Worker   const AString &methodName = method.MethodName;
3425*f6dc9357SAndroid Build Coastguard Worker   // methodName.RemoveChar(L'-');
3426*f6dc9357SAndroid Build Coastguard Worker   CMethodId hashID;
3427*f6dc9357SAndroid Build Coastguard Worker   if (!FindHashMethod(
3428*f6dc9357SAndroid Build Coastguard Worker       EXTERNAL_CODECS_LOC_VARS
3429*f6dc9357SAndroid Build Coastguard Worker       methodName, hashID))
3430*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
3431*f6dc9357SAndroid Build Coastguard Worker 
3432*f6dc9357SAndroid Build Coastguard Worker   /*
3433*f6dc9357SAndroid Build Coastguard Worker   // if will generate random data in each thread, instead of global data
3434*f6dc9357SAndroid Build Coastguard Worker   CMidAlignedBuffer buffer;
3435*f6dc9357SAndroid Build Coastguard Worker   if (!fileData)
3436*f6dc9357SAndroid Build Coastguard Worker   {
3437*f6dc9357SAndroid Build Coastguard Worker     ALLOC_WITH_HRESULT(&buffer, bufferSize)
3438*f6dc9357SAndroid Build Coastguard Worker     RandGen(buffer, bufferSize);
3439*f6dc9357SAndroid Build Coastguard Worker     fileData = buffer;
3440*f6dc9357SAndroid Build Coastguard Worker   }
3441*f6dc9357SAndroid Build Coastguard Worker   */
3442*f6dc9357SAndroid Build Coastguard Worker 
3443*f6dc9357SAndroid Build Coastguard Worker   const size_t bsize = (bufferSize == 0 ? 1 : bufferSize);
3444*f6dc9357SAndroid Build Coastguard Worker   UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize;
3445*f6dc9357SAndroid Build Coastguard Worker   if (numIterations == 0)
3446*f6dc9357SAndroid Build Coastguard Worker     numIterations = 1;
3447*f6dc9357SAndroid Build Coastguard Worker 
3448*f6dc9357SAndroid Build Coastguard Worker   CBenchInfoCalc progressInfoSpec;
3449*f6dc9357SAndroid Build Coastguard Worker   CBenchInfo info;
3450*f6dc9357SAndroid Build Coastguard Worker 
3451*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
3452*f6dc9357SAndroid Build Coastguard Worker   bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity();
3453*f6dc9357SAndroid Build Coastguard Worker 
3454*f6dc9357SAndroid Build Coastguard Worker   if (mtEncMode)
3455*f6dc9357SAndroid Build Coastguard Worker   {
3456*f6dc9357SAndroid Build Coastguard Worker     CCrcThreads threads;
3457*f6dc9357SAndroid Build Coastguard Worker     threads.Items = new CCrcInfo[numThreads];
3458*f6dc9357SAndroid Build Coastguard Worker     {
3459*f6dc9357SAndroid Build Coastguard Worker       WRes wres = threads.Common.StartEvent.Create();
3460*f6dc9357SAndroid Build Coastguard Worker       if (wres != 0)
3461*f6dc9357SAndroid Build Coastguard Worker         return HRESULT_FROM_WIN32(wres);
3462*f6dc9357SAndroid Build Coastguard Worker       threads.NeedClose = true;
3463*f6dc9357SAndroid Build Coastguard Worker     }
3464*f6dc9357SAndroid Build Coastguard Worker 
3465*f6dc9357SAndroid Build Coastguard Worker     UInt32 i;
3466*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3467*f6dc9357SAndroid Build Coastguard Worker     {
3468*f6dc9357SAndroid Build Coastguard Worker       CCrcInfo &ci = threads.Items[i];
3469*f6dc9357SAndroid Build Coastguard Worker       AString name;
3470*f6dc9357SAndroid Build Coastguard Worker       RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher))
3471*f6dc9357SAndroid Build Coastguard Worker       if (!ci.Hasher)
3472*f6dc9357SAndroid Build Coastguard Worker         return E_NOTIMPL;
3473*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ICompressSetCoderProperties> scp;
3474*f6dc9357SAndroid Build Coastguard Worker       ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
3475*f6dc9357SAndroid Build Coastguard Worker       if (scp)
3476*f6dc9357SAndroid Build Coastguard Worker       {
3477*f6dc9357SAndroid Build Coastguard Worker         RINOK(method.SetCoderProps(scp))
3478*f6dc9357SAndroid Build Coastguard Worker       }
3479*f6dc9357SAndroid Build Coastguard Worker 
3480*f6dc9357SAndroid Build Coastguard Worker       ci.Callback = _file;
3481*f6dc9357SAndroid Build Coastguard Worker       ci.Data = fileData;
3482*f6dc9357SAndroid Build Coastguard Worker       ci.NumIterations = numIterations;
3483*f6dc9357SAndroid Build Coastguard Worker       ci.Size = bufferSize;
3484*f6dc9357SAndroid Build Coastguard Worker       ci.CheckSumDefined = false;
3485*f6dc9357SAndroid Build Coastguard Worker       if (checkSum)
3486*f6dc9357SAndroid Build Coastguard Worker       {
3487*f6dc9357SAndroid Build Coastguard Worker         ci.CheckSum = *checkSum;
3488*f6dc9357SAndroid Build Coastguard Worker         ci.CheckSumDefined = true;
3489*f6dc9357SAndroid Build Coastguard Worker       }
3490*f6dc9357SAndroid Build Coastguard Worker 
3491*f6dc9357SAndroid Build Coastguard Worker       #ifdef USE_ALLOCA
3492*f6dc9357SAndroid Build Coastguard Worker       ci.AllocaSize = BENCH_ALLOCA_VALUE(i);
3493*f6dc9357SAndroid Build Coastguard Worker       #endif
3494*f6dc9357SAndroid Build Coastguard Worker     }
3495*f6dc9357SAndroid Build Coastguard Worker 
3496*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3497*f6dc9357SAndroid Build Coastguard Worker     {
3498*f6dc9357SAndroid Build Coastguard Worker       CCrcInfo &ci = threads.Items[i];
3499*f6dc9357SAndroid Build Coastguard Worker       ci.ThreadIndex = i;
3500*f6dc9357SAndroid Build Coastguard Worker       ci.Common = &threads.Common;
3501*f6dc9357SAndroid Build Coastguard Worker       ci.AffinityMode = *affinityMode;
3502*f6dc9357SAndroid Build Coastguard Worker       HRESULT hres = ci.CreateThread();
3503*f6dc9357SAndroid Build Coastguard Worker       if (ci.Thread.IsCreated())
3504*f6dc9357SAndroid Build Coastguard Worker         threads.NumThreads++;
3505*f6dc9357SAndroid Build Coastguard Worker       if (hres != 0)
3506*f6dc9357SAndroid Build Coastguard Worker         return hres;
3507*f6dc9357SAndroid Build Coastguard Worker     }
3508*f6dc9357SAndroid Build Coastguard Worker 
3509*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3510*f6dc9357SAndroid Build Coastguard Worker     {
3511*f6dc9357SAndroid Build Coastguard Worker       CCrcInfo &ci = threads.Items[i];
3512*f6dc9357SAndroid Build Coastguard Worker       WRes wres = ci.ReadyEvent.Lock();
3513*f6dc9357SAndroid Build Coastguard Worker       if (wres != 0)
3514*f6dc9357SAndroid Build Coastguard Worker         return HRESULT_FROM_WIN32(wres);
3515*f6dc9357SAndroid Build Coastguard Worker       RINOK(ci.Res)
3516*f6dc9357SAndroid Build Coastguard Worker     }
3517*f6dc9357SAndroid Build Coastguard Worker 
3518*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetStartTime();
3519*f6dc9357SAndroid Build Coastguard Worker 
3520*f6dc9357SAndroid Build Coastguard Worker     WRes wres = threads.StartAndWait();
3521*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
3522*f6dc9357SAndroid Build Coastguard Worker       return HRESULT_FROM_WIN32(wres);
3523*f6dc9357SAndroid Build Coastguard Worker 
3524*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetFinishTime(info);
3525*f6dc9357SAndroid Build Coastguard Worker 
3526*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numThreads; i++)
3527*f6dc9357SAndroid Build Coastguard Worker     {
3528*f6dc9357SAndroid Build Coastguard Worker       RINOK(threads.Items[i].Res)
3529*f6dc9357SAndroid Build Coastguard Worker       if (i != 0)
3530*f6dc9357SAndroid Build Coastguard Worker         if (threads.Items[i].CheckSum_Res !=
3531*f6dc9357SAndroid Build Coastguard Worker             threads.Items[i - 1].CheckSum_Res)
3532*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
3533*f6dc9357SAndroid Build Coastguard Worker     }
3534*f6dc9357SAndroid Build Coastguard Worker   }
3535*f6dc9357SAndroid Build Coastguard Worker   else
3536*f6dc9357SAndroid Build Coastguard Worker   #endif
3537*f6dc9357SAndroid Build Coastguard Worker   {
3538*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IHasher> hasher;
3539*f6dc9357SAndroid Build Coastguard Worker     AString name;
3540*f6dc9357SAndroid Build Coastguard Worker     RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher))
3541*f6dc9357SAndroid Build Coastguard Worker     if (!hasher)
3542*f6dc9357SAndroid Build Coastguard Worker       return E_NOTIMPL;
3543*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressSetCoderProperties> scp;
3544*f6dc9357SAndroid Build Coastguard Worker     hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
3545*f6dc9357SAndroid Build Coastguard Worker     if (scp)
3546*f6dc9357SAndroid Build Coastguard Worker     {
3547*f6dc9357SAndroid Build Coastguard Worker       RINOK(method.SetCoderProps(scp))
3548*f6dc9357SAndroid Build Coastguard Worker     }
3549*f6dc9357SAndroid Build Coastguard Worker     CCrcInfo_Base crcib;
3550*f6dc9357SAndroid Build Coastguard Worker     crcib.CreateLocalBuf = false;
3551*f6dc9357SAndroid Build Coastguard Worker     RINOK(crcib.Generate(fileData, bufferSize))
3552*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetStartTime();
3553*f6dc9357SAndroid Build Coastguard Worker     RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file))
3554*f6dc9357SAndroid Build Coastguard Worker     progressInfoSpec.SetFinishTime(info);
3555*f6dc9357SAndroid Build Coastguard Worker   }
3556*f6dc9357SAndroid Build Coastguard Worker 
3557*f6dc9357SAndroid Build Coastguard Worker 
3558*f6dc9357SAndroid Build Coastguard Worker   UInt64 unpSize = numIterations * bufferSize;
3559*f6dc9357SAndroid Build Coastguard Worker   UInt64 unpSizeThreads = unpSize * numThreads;
3560*f6dc9357SAndroid Build Coastguard Worker   info.UnpackSize = unpSizeThreads;
3561*f6dc9357SAndroid Build Coastguard Worker   info.PackSize = unpSizeThreads;
3562*f6dc9357SAndroid Build Coastguard Worker   info.NumIterations = 1;
3563*f6dc9357SAndroid Build Coastguard Worker 
3564*f6dc9357SAndroid Build Coastguard Worker   if (_file)
3565*f6dc9357SAndroid Build Coastguard Worker   {
3566*f6dc9357SAndroid Build Coastguard Worker     if (showRating)
3567*f6dc9357SAndroid Build Coastguard Worker     {
3568*f6dc9357SAndroid Build Coastguard Worker       UInt64 unpSizeThreads2 = unpSizeThreads;
3569*f6dc9357SAndroid Build Coastguard Worker       if (unpSizeThreads2 == 0)
3570*f6dc9357SAndroid Build Coastguard Worker         unpSizeThreads2 = numIterations * 1 * numThreads;
3571*f6dc9357SAndroid Build Coastguard Worker       const UInt64 numCommands = unpSizeThreads2 * complexity / 256;
3572*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rating = info.GetSpeed(numCommands);
3573*f6dc9357SAndroid Build Coastguard Worker       PrintResults(_file, info,
3574*f6dc9357SAndroid Build Coastguard Worker           benchWeight, rating,
3575*f6dc9357SAndroid Build Coastguard Worker           showFreq, cpuFreq, encodeRes);
3576*f6dc9357SAndroid Build Coastguard Worker     }
3577*f6dc9357SAndroid Build Coastguard Worker     RINOK(_file->CheckBreak())
3578*f6dc9357SAndroid Build Coastguard Worker   }
3579*f6dc9357SAndroid Build Coastguard Worker 
3580*f6dc9357SAndroid Build Coastguard Worker   speed = info.GetSpeed(unpSizeThreads);
3581*f6dc9357SAndroid Build Coastguard Worker   usage = info.GetUsage();
3582*f6dc9357SAndroid Build Coastguard Worker 
3583*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3584*f6dc9357SAndroid Build Coastguard Worker }
3585*f6dc9357SAndroid Build Coastguard Worker 
3586*f6dc9357SAndroid Build Coastguard Worker 
3587*f6dc9357SAndroid Build Coastguard Worker 
3588*f6dc9357SAndroid Build Coastguard Worker static HRESULT TotalBench_Hash(
3589*f6dc9357SAndroid Build Coastguard Worker     DECL_EXTERNAL_CODECS_LOC_VARS
3590*f6dc9357SAndroid Build Coastguard Worker     const COneMethodInfo &methodMask,
3591*f6dc9357SAndroid Build Coastguard Worker     UInt64 complexInCommands,
3592*f6dc9357SAndroid Build Coastguard Worker     UInt32 numThreads,
3593*f6dc9357SAndroid Build Coastguard Worker     size_t bufSize,
3594*f6dc9357SAndroid Build Coastguard Worker     const Byte *fileData,
3595*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback,
3596*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
3597*f6dc9357SAndroid Build Coastguard Worker     const CAffinityMode *affinityMode,
3598*f6dc9357SAndroid Build Coastguard Worker     #endif
3599*f6dc9357SAndroid Build Coastguard Worker     CTotalBenchRes *encodeRes,
3600*f6dc9357SAndroid Build Coastguard Worker     bool showFreq, UInt64 cpuFreq)
3601*f6dc9357SAndroid Build Coastguard Worker {
3602*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
3603*f6dc9357SAndroid Build Coastguard Worker   {
3604*f6dc9357SAndroid Build Coastguard Worker     const CBenchHash &bench = g_Hash[i];
3605*f6dc9357SAndroid Build Coastguard Worker     if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name))
3606*f6dc9357SAndroid Build Coastguard Worker       continue;
3607*f6dc9357SAndroid Build Coastguard Worker     PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
3608*f6dc9357SAndroid Build Coastguard Worker     // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
3609*f6dc9357SAndroid Build Coastguard Worker     // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
3610*f6dc9357SAndroid Build Coastguard Worker     // callback->BenchProps.EncComplex = bench.EncComplex;
3611*f6dc9357SAndroid Build Coastguard Worker 
3612*f6dc9357SAndroid Build Coastguard Worker     COneMethodInfo method;
3613*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant propVariant;
3614*f6dc9357SAndroid Build Coastguard Worker     propVariant = bench.Name;
3615*f6dc9357SAndroid Build Coastguard Worker     RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant))
3616*f6dc9357SAndroid Build Coastguard Worker 
3617*f6dc9357SAndroid Build Coastguard Worker     UInt64 speed, usage;
3618*f6dc9357SAndroid Build Coastguard Worker 
3619*f6dc9357SAndroid Build Coastguard Worker     const HRESULT res = CrcBench(
3620*f6dc9357SAndroid Build Coastguard Worker         EXTERNAL_CODECS_LOC_VARS
3621*f6dc9357SAndroid Build Coastguard Worker         complexInCommands,
3622*f6dc9357SAndroid Build Coastguard Worker         numThreads, bufSize, fileData,
3623*f6dc9357SAndroid Build Coastguard Worker         speed, usage,
3624*f6dc9357SAndroid Build Coastguard Worker         bench.Complex, bench.Weight,
3625*f6dc9357SAndroid Build Coastguard Worker         (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL,
3626*f6dc9357SAndroid Build Coastguard Worker         method,
3627*f6dc9357SAndroid Build Coastguard Worker         printCallback,
3628*f6dc9357SAndroid Build Coastguard Worker      #ifndef Z7_ST
3629*f6dc9357SAndroid Build Coastguard Worker         affinityMode,
3630*f6dc9357SAndroid Build Coastguard Worker      #endif
3631*f6dc9357SAndroid Build Coastguard Worker         true, // showRating
3632*f6dc9357SAndroid Build Coastguard Worker         encodeRes, showFreq, cpuFreq);
3633*f6dc9357SAndroid Build Coastguard Worker     if (res == E_NOTIMPL)
3634*f6dc9357SAndroid Build Coastguard Worker     {
3635*f6dc9357SAndroid Build Coastguard Worker       // callback->Print(" ---");
3636*f6dc9357SAndroid Build Coastguard Worker     }
3637*f6dc9357SAndroid Build Coastguard Worker     else
3638*f6dc9357SAndroid Build Coastguard Worker     {
3639*f6dc9357SAndroid Build Coastguard Worker       RINOK(res)
3640*f6dc9357SAndroid Build Coastguard Worker     }
3641*f6dc9357SAndroid Build Coastguard Worker     callback->NewLine();
3642*f6dc9357SAndroid Build Coastguard Worker   }
3643*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
3644*f6dc9357SAndroid Build Coastguard Worker }
3645*f6dc9357SAndroid Build Coastguard Worker 
3646*f6dc9357SAndroid Build Coastguard Worker struct CTempValues
3647*f6dc9357SAndroid Build Coastguard Worker {
3648*f6dc9357SAndroid Build Coastguard Worker   UInt64 *Values;
3649*f6dc9357SAndroid Build Coastguard Worker   CTempValues(): Values(NULL) {}
3650*f6dc9357SAndroid Build Coastguard Worker   void Alloc(UInt32 num) { Values = new UInt64[num]; }
3651*f6dc9357SAndroid Build Coastguard Worker   ~CTempValues() { delete []Values; }
3652*f6dc9357SAndroid Build Coastguard Worker };
3653*f6dc9357SAndroid Build Coastguard Worker 
3654*f6dc9357SAndroid Build Coastguard Worker static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
3655*f6dc9357SAndroid Build Coastguard Worker {
3656*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *end;
3657*f6dc9357SAndroid Build Coastguard Worker   UInt64 result = ConvertStringToUInt64(s, &end);
3658*f6dc9357SAndroid Build Coastguard Worker   if (*end != 0 || s.IsEmpty())
3659*f6dc9357SAndroid Build Coastguard Worker     prop = s;
3660*f6dc9357SAndroid Build Coastguard Worker   else if (result <= (UInt32)0xFFFFFFFF)
3661*f6dc9357SAndroid Build Coastguard Worker     prop = (UInt32)result;
3662*f6dc9357SAndroid Build Coastguard Worker   else
3663*f6dc9357SAndroid Build Coastguard Worker     prop = result;
3664*f6dc9357SAndroid Build Coastguard Worker }
3665*f6dc9357SAndroid Build Coastguard Worker 
3666*f6dc9357SAndroid Build Coastguard Worker 
3667*f6dc9357SAndroid Build Coastguard Worker static bool AreSameMethodNames(const char *fullName, const char *shortName)
3668*f6dc9357SAndroid Build Coastguard Worker {
3669*f6dc9357SAndroid Build Coastguard Worker   return StringsAreEqualNoCase_Ascii(fullName, shortName);
3670*f6dc9357SAndroid Build Coastguard Worker }
3671*f6dc9357SAndroid Build Coastguard Worker 
3672*f6dc9357SAndroid Build Coastguard Worker 
3673*f6dc9357SAndroid Build Coastguard Worker 
3674*f6dc9357SAndroid Build Coastguard Worker 
3675*f6dc9357SAndroid Build Coastguard Worker static void Print_Usage_and_Threads(IBenchPrintCallback &f, UInt64 usage, UInt32 threads)
3676*f6dc9357SAndroid Build Coastguard Worker {
3677*f6dc9357SAndroid Build Coastguard Worker   PrintRequirements(f, "usage:", true, usage, "Benchmark threads:   ", threads);
3678*f6dc9357SAndroid Build Coastguard Worker }
3679*f6dc9357SAndroid Build Coastguard Worker 
3680*f6dc9357SAndroid Build Coastguard Worker 
3681*f6dc9357SAndroid Build Coastguard Worker static void Print_Delimiter(IBenchPrintCallback &f)
3682*f6dc9357SAndroid Build Coastguard Worker {
3683*f6dc9357SAndroid Build Coastguard Worker   f.Print(" |");
3684*f6dc9357SAndroid Build Coastguard Worker }
3685*f6dc9357SAndroid Build Coastguard Worker 
3686*f6dc9357SAndroid Build Coastguard Worker static void Print_Pow(IBenchPrintCallback &f, unsigned pow)
3687*f6dc9357SAndroid Build Coastguard Worker {
3688*f6dc9357SAndroid Build Coastguard Worker   char s[16];
3689*f6dc9357SAndroid Build Coastguard Worker   ConvertUInt32ToString(pow, s);
3690*f6dc9357SAndroid Build Coastguard Worker   unsigned pos = MyStringLen(s);
3691*f6dc9357SAndroid Build Coastguard Worker   s[pos++] = ':';
3692*f6dc9357SAndroid Build Coastguard Worker   s[pos] = 0;
3693*f6dc9357SAndroid Build Coastguard Worker   PrintLeft(f, s, kFieldSize_SmallName); // 4
3694*f6dc9357SAndroid Build Coastguard Worker }
3695*f6dc9357SAndroid Build Coastguard Worker 
3696*f6dc9357SAndroid Build Coastguard Worker static void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f,
3697*f6dc9357SAndroid Build Coastguard Worker     UInt64 usage, UInt64 speed)
3698*f6dc9357SAndroid Build Coastguard Worker {
3699*f6dc9357SAndroid Build Coastguard Worker   PrintUsage(f, usage, kFieldSize_Usage);
3700*f6dc9357SAndroid Build Coastguard Worker   PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed);
3701*f6dc9357SAndroid Build Coastguard Worker }
3702*f6dc9357SAndroid Build Coastguard Worker 
3703*f6dc9357SAndroid Build Coastguard Worker 
3704*f6dc9357SAndroid Build Coastguard Worker HRESULT Bench(
3705*f6dc9357SAndroid Build Coastguard Worker     DECL_EXTERNAL_CODECS_LOC_VARS
3706*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback *printCallback,
3707*f6dc9357SAndroid Build Coastguard Worker     IBenchCallback *benchCallback,
3708*f6dc9357SAndroid Build Coastguard Worker     const CObjectVector<CProperty> &props,
3709*f6dc9357SAndroid Build Coastguard Worker     UInt32 numIterations,
3710*f6dc9357SAndroid Build Coastguard Worker     bool multiDict,
3711*f6dc9357SAndroid Build Coastguard Worker     IBenchFreqCallback *freqCallback)
3712*f6dc9357SAndroid Build Coastguard Worker {
3713*f6dc9357SAndroid Build Coastguard Worker   // for (int y = 0; y < 10000; y++)
3714*f6dc9357SAndroid Build Coastguard Worker   if (!CrcInternalTest())
3715*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
3716*f6dc9357SAndroid Build Coastguard Worker 
3717*f6dc9357SAndroid Build Coastguard Worker   UInt32 numCPUs = 1;
3718*f6dc9357SAndroid Build Coastguard Worker   size_t ramSize = (size_t)sizeof(size_t) << 29;
3719*f6dc9357SAndroid Build Coastguard Worker 
3720*f6dc9357SAndroid Build Coastguard Worker   NSystem::CProcessAffinity threadsInfo;
3721*f6dc9357SAndroid Build Coastguard Worker   threadsInfo.InitST();
3722*f6dc9357SAndroid Build Coastguard Worker 
3723*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
3724*f6dc9357SAndroid Build Coastguard Worker 
3725*f6dc9357SAndroid Build Coastguard Worker   if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0)
3726*f6dc9357SAndroid Build Coastguard Worker     numCPUs = threadsInfo.GetNumProcessThreads();
3727*f6dc9357SAndroid Build Coastguard Worker   else
3728*f6dc9357SAndroid Build Coastguard Worker     numCPUs = NSystem::GetNumberOfProcessors();
3729*f6dc9357SAndroid Build Coastguard Worker 
3730*f6dc9357SAndroid Build Coastguard Worker   #endif
3731*f6dc9357SAndroid Build Coastguard Worker 
3732*f6dc9357SAndroid Build Coastguard Worker   // numCPUs = 24;
3733*f6dc9357SAndroid Build Coastguard Worker   /*
3734*f6dc9357SAndroid Build Coastguard Worker   {
3735*f6dc9357SAndroid Build Coastguard Worker     DWORD_PTR mask = (1 << 0);
3736*f6dc9357SAndroid Build Coastguard Worker     DWORD_PTR old = SetThreadAffinityMask(GetCurrentThread(), mask);
3737*f6dc9357SAndroid Build Coastguard Worker     old = old;
3738*f6dc9357SAndroid Build Coastguard Worker     DWORD_PTR old2 = SetThreadAffinityMask(GetCurrentThread(), mask);
3739*f6dc9357SAndroid Build Coastguard Worker     old2 = old2;
3740*f6dc9357SAndroid Build Coastguard Worker     return 0;
3741*f6dc9357SAndroid Build Coastguard Worker   }
3742*f6dc9357SAndroid Build Coastguard Worker   */
3743*f6dc9357SAndroid Build Coastguard Worker 
3744*f6dc9357SAndroid Build Coastguard Worker   const bool ramSize_Defined = NSystem::GetRamSize(ramSize);
3745*f6dc9357SAndroid Build Coastguard Worker 
3746*f6dc9357SAndroid Build Coastguard Worker   UInt32 numThreadsSpecified = numCPUs;
3747*f6dc9357SAndroid Build Coastguard Worker   bool needSetComplexity = false;
3748*f6dc9357SAndroid Build Coastguard Worker   UInt32 testTimeMs = kComplexInMs;
3749*f6dc9357SAndroid Build Coastguard Worker   UInt32 startDicLog = 22;
3750*f6dc9357SAndroid Build Coastguard Worker   bool startDicLog_Defined = false;
3751*f6dc9357SAndroid Build Coastguard Worker   UInt64 specifiedFreq = 0;
3752*f6dc9357SAndroid Build Coastguard Worker   bool multiThreadTests = false;
3753*f6dc9357SAndroid Build Coastguard Worker   UInt64 complexInCommands = kComplexInCommands;
3754*f6dc9357SAndroid Build Coastguard Worker   UInt32 numThreads_Start = 1;
3755*f6dc9357SAndroid Build Coastguard Worker 
3756*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
3757*f6dc9357SAndroid Build Coastguard Worker   CAffinityMode affinityMode;
3758*f6dc9357SAndroid Build Coastguard Worker   #endif
3759*f6dc9357SAndroid Build Coastguard Worker 
3760*f6dc9357SAndroid Build Coastguard Worker 
3761*f6dc9357SAndroid Build Coastguard Worker   COneMethodInfo method;
3762*f6dc9357SAndroid Build Coastguard Worker 
3763*f6dc9357SAndroid Build Coastguard Worker   CMidAlignedBuffer fileDataBuffer;
3764*f6dc9357SAndroid Build Coastguard Worker   bool use_fileData = false;
3765*f6dc9357SAndroid Build Coastguard Worker   bool isFixedDict = false;
3766*f6dc9357SAndroid Build Coastguard Worker 
3767*f6dc9357SAndroid Build Coastguard Worker   {
3768*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
3769*f6dc9357SAndroid Build Coastguard Worker 
3770*f6dc9357SAndroid Build Coastguard Worker   if (printCallback)
3771*f6dc9357SAndroid Build Coastguard Worker   {
3772*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < props.Size(); i++)
3773*f6dc9357SAndroid Build Coastguard Worker     {
3774*f6dc9357SAndroid Build Coastguard Worker       const CProperty &property = props[i];
3775*f6dc9357SAndroid Build Coastguard Worker       printCallback->Print(" ");
3776*f6dc9357SAndroid Build Coastguard Worker       printCallback->Print(GetAnsiString(property.Name));
3777*f6dc9357SAndroid Build Coastguard Worker       if (!property.Value.IsEmpty())
3778*f6dc9357SAndroid Build Coastguard Worker       {
3779*f6dc9357SAndroid Build Coastguard Worker         printCallback->Print("=");
3780*f6dc9357SAndroid Build Coastguard Worker         printCallback->Print(GetAnsiString(property.Value));
3781*f6dc9357SAndroid Build Coastguard Worker       }
3782*f6dc9357SAndroid Build Coastguard Worker     }
3783*f6dc9357SAndroid Build Coastguard Worker     if (!props.IsEmpty())
3784*f6dc9357SAndroid Build Coastguard Worker       printCallback->NewLine();
3785*f6dc9357SAndroid Build Coastguard Worker   }
3786*f6dc9357SAndroid Build Coastguard Worker 
3787*f6dc9357SAndroid Build Coastguard Worker 
3788*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < props.Size(); i++)
3789*f6dc9357SAndroid Build Coastguard Worker   {
3790*f6dc9357SAndroid Build Coastguard Worker     const CProperty &property = props[i];
3791*f6dc9357SAndroid Build Coastguard Worker     UString name (property.Name);
3792*f6dc9357SAndroid Build Coastguard Worker     name.MakeLower_Ascii();
3793*f6dc9357SAndroid Build Coastguard Worker 
3794*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("file"))
3795*f6dc9357SAndroid Build Coastguard Worker     {
3796*f6dc9357SAndroid Build Coastguard Worker       if (property.Value.IsEmpty())
3797*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
3798*f6dc9357SAndroid Build Coastguard Worker 
3799*f6dc9357SAndroid Build Coastguard Worker       NFile::NIO::CInFile file;
3800*f6dc9357SAndroid Build Coastguard Worker       if (!file.Open(us2fs(property.Value)))
3801*f6dc9357SAndroid Build Coastguard Worker         return GetLastError_noZero_HRESULT();
3802*f6dc9357SAndroid Build Coastguard Worker       size_t len;
3803*f6dc9357SAndroid Build Coastguard Worker       {
3804*f6dc9357SAndroid Build Coastguard Worker         UInt64 len64;
3805*f6dc9357SAndroid Build Coastguard Worker         if (!file.GetLength(len64))
3806*f6dc9357SAndroid Build Coastguard Worker           return GetLastError_noZero_HRESULT();
3807*f6dc9357SAndroid Build Coastguard Worker         if (printCallback)
3808*f6dc9357SAndroid Build Coastguard Worker         {
3809*f6dc9357SAndroid Build Coastguard Worker           printCallback->Print("file size =");
3810*f6dc9357SAndroid Build Coastguard Worker           PrintNumber(*printCallback, len64, 0);
3811*f6dc9357SAndroid Build Coastguard Worker           printCallback->NewLine();
3812*f6dc9357SAndroid Build Coastguard Worker         }
3813*f6dc9357SAndroid Build Coastguard Worker         len = (size_t)len64;
3814*f6dc9357SAndroid Build Coastguard Worker         if (len != len64)
3815*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
3816*f6dc9357SAndroid Build Coastguard Worker       }
3817*f6dc9357SAndroid Build Coastguard Worker 
3818*f6dc9357SAndroid Build Coastguard Worker       // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here
3819*f6dc9357SAndroid Build Coastguard Worker 
3820*f6dc9357SAndroid Build Coastguard Worker       ALLOC_WITH_HRESULT(&fileDataBuffer, len)
3821*f6dc9357SAndroid Build Coastguard Worker       use_fileData = true;
3822*f6dc9357SAndroid Build Coastguard Worker 
3823*f6dc9357SAndroid Build Coastguard Worker       {
3824*f6dc9357SAndroid Build Coastguard Worker         size_t processed;
3825*f6dc9357SAndroid Build Coastguard Worker         if (!file.ReadFull((Byte *)fileDataBuffer, len, processed))
3826*f6dc9357SAndroid Build Coastguard Worker           return GetLastError_noZero_HRESULT();
3827*f6dc9357SAndroid Build Coastguard Worker         if (processed != len)
3828*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL;
3829*f6dc9357SAndroid Build Coastguard Worker       }
3830*f6dc9357SAndroid Build Coastguard Worker       continue;
3831*f6dc9357SAndroid Build Coastguard Worker     }
3832*f6dc9357SAndroid Build Coastguard Worker 
3833*f6dc9357SAndroid Build Coastguard Worker     NCOM::CPropVariant propVariant;
3834*f6dc9357SAndroid Build Coastguard Worker     if (!property.Value.IsEmpty())
3835*f6dc9357SAndroid Build Coastguard Worker       ParseNumberString(property.Value, propVariant);
3836*f6dc9357SAndroid Build Coastguard Worker 
3837*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("time"))
3838*f6dc9357SAndroid Build Coastguard Worker     {
3839*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
3840*f6dc9357SAndroid Build Coastguard Worker       needSetComplexity = true;
3841*f6dc9357SAndroid Build Coastguard Worker       testTimeMs *= 1000;
3842*f6dc9357SAndroid Build Coastguard Worker       continue;
3843*f6dc9357SAndroid Build Coastguard Worker     }
3844*f6dc9357SAndroid Build Coastguard Worker 
3845*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("timems"))
3846*f6dc9357SAndroid Build Coastguard Worker     {
3847*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs))
3848*f6dc9357SAndroid Build Coastguard Worker       needSetComplexity = true;
3849*f6dc9357SAndroid Build Coastguard Worker       continue;
3850*f6dc9357SAndroid Build Coastguard Worker     }
3851*f6dc9357SAndroid Build Coastguard Worker 
3852*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("tic"))
3853*f6dc9357SAndroid Build Coastguard Worker     {
3854*f6dc9357SAndroid Build Coastguard Worker       UInt32 v;
3855*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, v))
3856*f6dc9357SAndroid Build Coastguard Worker       if (v >= 64)
3857*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
3858*f6dc9357SAndroid Build Coastguard Worker       complexInCommands = (UInt64)1 << v;
3859*f6dc9357SAndroid Build Coastguard Worker       continue;
3860*f6dc9357SAndroid Build Coastguard Worker     }
3861*f6dc9357SAndroid Build Coastguard Worker 
3862*f6dc9357SAndroid Build Coastguard Worker     const bool isCurrent_fixedDict = name.IsEqualTo("df");
3863*f6dc9357SAndroid Build Coastguard Worker     if (isCurrent_fixedDict)
3864*f6dc9357SAndroid Build Coastguard Worker       isFixedDict = true;
3865*f6dc9357SAndroid Build Coastguard Worker     if (isCurrent_fixedDict || name.IsEqualTo("ds"))
3866*f6dc9357SAndroid Build Coastguard Worker     {
3867*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog))
3868*f6dc9357SAndroid Build Coastguard Worker       if (startDicLog > 32)
3869*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
3870*f6dc9357SAndroid Build Coastguard Worker       startDicLog_Defined = true;
3871*f6dc9357SAndroid Build Coastguard Worker       continue;
3872*f6dc9357SAndroid Build Coastguard Worker     }
3873*f6dc9357SAndroid Build Coastguard Worker 
3874*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("mts"))
3875*f6dc9357SAndroid Build Coastguard Worker     {
3876*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start))
3877*f6dc9357SAndroid Build Coastguard Worker       continue;
3878*f6dc9357SAndroid Build Coastguard Worker     }
3879*f6dc9357SAndroid Build Coastguard Worker 
3880*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("af"))
3881*f6dc9357SAndroid Build Coastguard Worker     {
3882*f6dc9357SAndroid Build Coastguard Worker       UInt32 bundle;
3883*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, bundle))
3884*f6dc9357SAndroid Build Coastguard Worker       if (bundle > 0 && bundle < numCPUs)
3885*f6dc9357SAndroid Build Coastguard Worker       {
3886*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
3887*f6dc9357SAndroid Build Coastguard Worker         affinityMode.SetLevels(numCPUs, 2);
3888*f6dc9357SAndroid Build Coastguard Worker         affinityMode.NumBundleThreads = bundle;
3889*f6dc9357SAndroid Build Coastguard Worker         #endif
3890*f6dc9357SAndroid Build Coastguard Worker       }
3891*f6dc9357SAndroid Build Coastguard Worker       continue;
3892*f6dc9357SAndroid Build Coastguard Worker     }
3893*f6dc9357SAndroid Build Coastguard Worker 
3894*f6dc9357SAndroid Build Coastguard Worker     if (name.IsEqualTo("freq"))
3895*f6dc9357SAndroid Build Coastguard Worker     {
3896*f6dc9357SAndroid Build Coastguard Worker       UInt32 freq32 = 0;
3897*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParsePropToUInt32(UString(), propVariant, freq32))
3898*f6dc9357SAndroid Build Coastguard Worker       if (freq32 == 0)
3899*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
3900*f6dc9357SAndroid Build Coastguard Worker       specifiedFreq = (UInt64)freq32 * 1000000;
3901*f6dc9357SAndroid Build Coastguard Worker 
3902*f6dc9357SAndroid Build Coastguard Worker       if (printCallback)
3903*f6dc9357SAndroid Build Coastguard Worker       {
3904*f6dc9357SAndroid Build Coastguard Worker         printCallback->Print("freq=");
3905*f6dc9357SAndroid Build Coastguard Worker         PrintNumber(*printCallback, freq32, 0);
3906*f6dc9357SAndroid Build Coastguard Worker         printCallback->NewLine();
3907*f6dc9357SAndroid Build Coastguard Worker       }
3908*f6dc9357SAndroid Build Coastguard Worker 
3909*f6dc9357SAndroid Build Coastguard Worker       continue;
3910*f6dc9357SAndroid Build Coastguard Worker     }
3911*f6dc9357SAndroid Build Coastguard Worker 
3912*f6dc9357SAndroid Build Coastguard Worker     if (name.IsPrefixedBy_Ascii_NoCase("mt"))
3913*f6dc9357SAndroid Build Coastguard Worker     {
3914*f6dc9357SAndroid Build Coastguard Worker       const UString s = name.Ptr(2);
3915*f6dc9357SAndroid Build Coastguard Worker       if (s.IsEqualTo("*")
3916*f6dc9357SAndroid Build Coastguard Worker           || (s.IsEmpty()
3917*f6dc9357SAndroid Build Coastguard Worker             && propVariant.vt == VT_BSTR
3918*f6dc9357SAndroid Build Coastguard Worker             && StringsAreEqual_Ascii(propVariant.bstrVal, "*")))
3919*f6dc9357SAndroid Build Coastguard Worker       {
3920*f6dc9357SAndroid Build Coastguard Worker         multiThreadTests = true;
3921*f6dc9357SAndroid Build Coastguard Worker         continue;
3922*f6dc9357SAndroid Build Coastguard Worker       }
3923*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
3924*f6dc9357SAndroid Build Coastguard Worker       RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified))
3925*f6dc9357SAndroid Build Coastguard Worker       #endif
3926*f6dc9357SAndroid Build Coastguard Worker       continue;
3927*f6dc9357SAndroid Build Coastguard Worker     }
3928*f6dc9357SAndroid Build Coastguard Worker 
3929*f6dc9357SAndroid Build Coastguard Worker     RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant))
3930*f6dc9357SAndroid Build Coastguard Worker   }
3931*f6dc9357SAndroid Build Coastguard Worker   }
3932*f6dc9357SAndroid Build Coastguard Worker 
3933*f6dc9357SAndroid Build Coastguard Worker   if (printCallback)
3934*f6dc9357SAndroid Build Coastguard Worker   {
3935*f6dc9357SAndroid Build Coastguard Worker     AString s;
3936*f6dc9357SAndroid Build Coastguard Worker 
3937*f6dc9357SAndroid Build Coastguard Worker #if 1 || !defined(Z7_MSC_VER_ORIGINAL) || (Z7_MSC_VER_ORIGINAL >= 1900)
3938*f6dc9357SAndroid Build Coastguard Worker     s += "Compiler: ";
3939*f6dc9357SAndroid Build Coastguard Worker     GetCompiler(s);
3940*f6dc9357SAndroid Build Coastguard Worker     printCallback->Print(s);
3941*f6dc9357SAndroid Build Coastguard Worker     printCallback->NewLine();
3942*f6dc9357SAndroid Build Coastguard Worker     s.Empty();
3943*f6dc9357SAndroid Build Coastguard Worker #endif
3944*f6dc9357SAndroid Build Coastguard Worker 
3945*f6dc9357SAndroid Build Coastguard Worker     GetSystemInfoText(s);
3946*f6dc9357SAndroid Build Coastguard Worker     printCallback->Print(s);
3947*f6dc9357SAndroid Build Coastguard Worker     printCallback->NewLine();
3948*f6dc9357SAndroid Build Coastguard Worker   }
3949*f6dc9357SAndroid Build Coastguard Worker 
3950*f6dc9357SAndroid Build Coastguard Worker   if (printCallback)
3951*f6dc9357SAndroid Build Coastguard Worker   {
3952*f6dc9357SAndroid Build Coastguard Worker     printCallback->Print("1T CPU Freq (MHz):");
3953*f6dc9357SAndroid Build Coastguard Worker   }
3954*f6dc9357SAndroid Build Coastguard Worker 
3955*f6dc9357SAndroid Build Coastguard Worker   if (printCallback || freqCallback)
3956*f6dc9357SAndroid Build Coastguard Worker   {
3957*f6dc9357SAndroid Build Coastguard Worker     UInt64 numMilCommands = 1 << 6;
3958*f6dc9357SAndroid Build Coastguard Worker     if (specifiedFreq != 0)
3959*f6dc9357SAndroid Build Coastguard Worker     {
3960*f6dc9357SAndroid Build Coastguard Worker       while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
3961*f6dc9357SAndroid Build Coastguard Worker         numMilCommands >>= 1;
3962*f6dc9357SAndroid Build Coastguard Worker     }
3963*f6dc9357SAndroid Build Coastguard Worker 
3964*f6dc9357SAndroid Build Coastguard Worker     for (int jj = 0;; jj++)
3965*f6dc9357SAndroid Build Coastguard Worker     {
3966*f6dc9357SAndroid Build Coastguard Worker       if (printCallback)
3967*f6dc9357SAndroid Build Coastguard Worker         RINOK(printCallback->CheckBreak())
3968*f6dc9357SAndroid Build Coastguard Worker 
3969*f6dc9357SAndroid Build Coastguard Worker       UInt64 start = ::GetTimeCount();
3970*f6dc9357SAndroid Build Coastguard Worker       UInt32 sum = (UInt32)start;
3971*f6dc9357SAndroid Build Coastguard Worker       sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
3972*f6dc9357SAndroid Build Coastguard Worker       if (sum == 0xF1541213)
3973*f6dc9357SAndroid Build Coastguard Worker         if (printCallback)
3974*f6dc9357SAndroid Build Coastguard Worker           printCallback->Print("");
3975*f6dc9357SAndroid Build Coastguard Worker       const UInt64 realDelta = ::GetTimeCount() - start;
3976*f6dc9357SAndroid Build Coastguard Worker       start = realDelta;
3977*f6dc9357SAndroid Build Coastguard Worker       if (start == 0)
3978*f6dc9357SAndroid Build Coastguard Worker         start = 1;
3979*f6dc9357SAndroid Build Coastguard Worker       if (start > (UInt64)1 << 61)
3980*f6dc9357SAndroid Build Coastguard Worker         start = 1;
3981*f6dc9357SAndroid Build Coastguard Worker       const UInt64 freq = GetFreq();
3982*f6dc9357SAndroid Build Coastguard Worker       // mips is constant in some compilers
3983*f6dc9357SAndroid Build Coastguard Worker       const UInt64 hzVal = MyMultDiv64(numMilCommands * 1000000, freq, start);
3984*f6dc9357SAndroid Build Coastguard Worker       const UInt64 mipsVal = numMilCommands * freq / start;
3985*f6dc9357SAndroid Build Coastguard Worker       if (printCallback)
3986*f6dc9357SAndroid Build Coastguard Worker       {
3987*f6dc9357SAndroid Build Coastguard Worker         if (realDelta == 0)
3988*f6dc9357SAndroid Build Coastguard Worker         {
3989*f6dc9357SAndroid Build Coastguard Worker           printCallback->Print(" -");
3990*f6dc9357SAndroid Build Coastguard Worker         }
3991*f6dc9357SAndroid Build Coastguard Worker         else
3992*f6dc9357SAndroid Build Coastguard Worker         {
3993*f6dc9357SAndroid Build Coastguard Worker           // PrintNumber(*printCallback, start, 0);
3994*f6dc9357SAndroid Build Coastguard Worker           PrintNumber(*printCallback, mipsVal, 5);
3995*f6dc9357SAndroid Build Coastguard Worker         }
3996*f6dc9357SAndroid Build Coastguard Worker       }
3997*f6dc9357SAndroid Build Coastguard Worker       if (freqCallback)
3998*f6dc9357SAndroid Build Coastguard Worker       {
3999*f6dc9357SAndroid Build Coastguard Worker         RINOK(freqCallback->AddCpuFreq(1, hzVal, kBenchmarkUsageMult))
4000*f6dc9357SAndroid Build Coastguard Worker       }
4001*f6dc9357SAndroid Build Coastguard Worker 
4002*f6dc9357SAndroid Build Coastguard Worker       if (jj >= 1)
4003*f6dc9357SAndroid Build Coastguard Worker       {
4004*f6dc9357SAndroid Build Coastguard Worker         bool needStop = (numMilCommands >= (1 <<
4005*f6dc9357SAndroid Build Coastguard Worker           #ifdef _DEBUG
4006*f6dc9357SAndroid Build Coastguard Worker             7
4007*f6dc9357SAndroid Build Coastguard Worker           #else
4008*f6dc9357SAndroid Build Coastguard Worker             11
4009*f6dc9357SAndroid Build Coastguard Worker           #endif
4010*f6dc9357SAndroid Build Coastguard Worker           ));
4011*f6dc9357SAndroid Build Coastguard Worker         if (start >= freq * 16)
4012*f6dc9357SAndroid Build Coastguard Worker         {
4013*f6dc9357SAndroid Build Coastguard Worker           printCallback->Print(" (Cmplx)");
4014*f6dc9357SAndroid Build Coastguard Worker           if (!freqCallback) // we don't want complexity change for old gui lzma benchmark
4015*f6dc9357SAndroid Build Coastguard Worker           {
4016*f6dc9357SAndroid Build Coastguard Worker             needSetComplexity = true;
4017*f6dc9357SAndroid Build Coastguard Worker           }
4018*f6dc9357SAndroid Build Coastguard Worker           needStop = true;
4019*f6dc9357SAndroid Build Coastguard Worker         }
4020*f6dc9357SAndroid Build Coastguard Worker         if (needSetComplexity)
4021*f6dc9357SAndroid Build Coastguard Worker           SetComplexCommandsMs(testTimeMs, false, mipsVal * 1000000, complexInCommands);
4022*f6dc9357SAndroid Build Coastguard Worker         if (needStop)
4023*f6dc9357SAndroid Build Coastguard Worker           break;
4024*f6dc9357SAndroid Build Coastguard Worker         numMilCommands <<= 1;
4025*f6dc9357SAndroid Build Coastguard Worker       }
4026*f6dc9357SAndroid Build Coastguard Worker     }
4027*f6dc9357SAndroid Build Coastguard Worker     if (freqCallback)
4028*f6dc9357SAndroid Build Coastguard Worker     {
4029*f6dc9357SAndroid Build Coastguard Worker       RINOK(freqCallback->FreqsFinished(1))
4030*f6dc9357SAndroid Build Coastguard Worker     }
4031*f6dc9357SAndroid Build Coastguard Worker   }
4032*f6dc9357SAndroid Build Coastguard Worker 
4033*f6dc9357SAndroid Build Coastguard Worker   if (printCallback || freqCallback)
4034*f6dc9357SAndroid Build Coastguard Worker   for (unsigned test = 0; test < 3; test++)
4035*f6dc9357SAndroid Build Coastguard Worker   {
4036*f6dc9357SAndroid Build Coastguard Worker     if (numThreadsSpecified < 2)
4037*f6dc9357SAndroid Build Coastguard Worker     {
4038*f6dc9357SAndroid Build Coastguard Worker       // if (test == 1)
4039*f6dc9357SAndroid Build Coastguard Worker       break;
4040*f6dc9357SAndroid Build Coastguard Worker     }
4041*f6dc9357SAndroid Build Coastguard Worker     if (test == 2 && numThreadsSpecified <= numCPUs)
4042*f6dc9357SAndroid Build Coastguard Worker       break;
4043*f6dc9357SAndroid Build Coastguard Worker     if (printCallback)
4044*f6dc9357SAndroid Build Coastguard Worker       printCallback->NewLine();
4045*f6dc9357SAndroid Build Coastguard Worker 
4046*f6dc9357SAndroid Build Coastguard Worker     /* it can show incorrect frequency for HT threads. */
4047*f6dc9357SAndroid Build Coastguard Worker 
4048*f6dc9357SAndroid Build Coastguard Worker     UInt32 numThreads = numThreadsSpecified;
4049*f6dc9357SAndroid Build Coastguard Worker     if (test < 2)
4050*f6dc9357SAndroid Build Coastguard Worker     {
4051*f6dc9357SAndroid Build Coastguard Worker       if (numThreads >= numCPUs)
4052*f6dc9357SAndroid Build Coastguard Worker         numThreads = numCPUs;
4053*f6dc9357SAndroid Build Coastguard Worker       if (test == 0)
4054*f6dc9357SAndroid Build Coastguard Worker         numThreads /= 2;
4055*f6dc9357SAndroid Build Coastguard Worker     }
4056*f6dc9357SAndroid Build Coastguard Worker     if (numThreads < 1)
4057*f6dc9357SAndroid Build Coastguard Worker       numThreads = 1;
4058*f6dc9357SAndroid Build Coastguard Worker 
4059*f6dc9357SAndroid Build Coastguard Worker     if (printCallback)
4060*f6dc9357SAndroid Build Coastguard Worker     {
4061*f6dc9357SAndroid Build Coastguard Worker       char s[128];
4062*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt64ToString(numThreads, s);
4063*f6dc9357SAndroid Build Coastguard Worker       printCallback->Print(s);
4064*f6dc9357SAndroid Build Coastguard Worker       printCallback->Print("T CPU Freq (MHz):");
4065*f6dc9357SAndroid Build Coastguard Worker     }
4066*f6dc9357SAndroid Build Coastguard Worker     UInt64 numMilCommands = 1 <<
4067*f6dc9357SAndroid Build Coastguard Worker           #ifdef _DEBUG
4068*f6dc9357SAndroid Build Coastguard Worker             7;
4069*f6dc9357SAndroid Build Coastguard Worker           #else
4070*f6dc9357SAndroid Build Coastguard Worker             10;
4071*f6dc9357SAndroid Build Coastguard Worker           #endif
4072*f6dc9357SAndroid Build Coastguard Worker 
4073*f6dc9357SAndroid Build Coastguard Worker     if (specifiedFreq != 0)
4074*f6dc9357SAndroid Build Coastguard Worker     {
4075*f6dc9357SAndroid Build Coastguard Worker       while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
4076*f6dc9357SAndroid Build Coastguard Worker         numMilCommands >>= 1;
4077*f6dc9357SAndroid Build Coastguard Worker     }
4078*f6dc9357SAndroid Build Coastguard Worker 
4079*f6dc9357SAndroid Build Coastguard Worker     // for (int jj = 0;; jj++)
4080*f6dc9357SAndroid Build Coastguard Worker     for (;;)
4081*f6dc9357SAndroid Build Coastguard Worker     {
4082*f6dc9357SAndroid Build Coastguard Worker       if (printCallback)
4083*f6dc9357SAndroid Build Coastguard Worker         RINOK(printCallback->CheckBreak())
4084*f6dc9357SAndroid Build Coastguard Worker 
4085*f6dc9357SAndroid Build Coastguard Worker       {
4086*f6dc9357SAndroid Build Coastguard Worker         // PrintLeft(f, "CPU", kFieldSize_Name);
4087*f6dc9357SAndroid Build Coastguard Worker 
4088*f6dc9357SAndroid Build Coastguard Worker         // UInt32 resVal;
4089*f6dc9357SAndroid Build Coastguard Worker 
4090*f6dc9357SAndroid Build Coastguard Worker         CFreqBench fb;
4091*f6dc9357SAndroid Build Coastguard Worker         fb.complexInCommands = numMilCommands * 1000000;
4092*f6dc9357SAndroid Build Coastguard Worker         fb.numThreads = numThreads;
4093*f6dc9357SAndroid Build Coastguard Worker         // showFreq;
4094*f6dc9357SAndroid Build Coastguard Worker         // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
4095*f6dc9357SAndroid Build Coastguard Worker         fb.showFreq = true;
4096*f6dc9357SAndroid Build Coastguard Worker         fb.specifiedFreq = 1;
4097*f6dc9357SAndroid Build Coastguard Worker 
4098*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = fb.FreqBench(NULL /* printCallback */
4099*f6dc9357SAndroid Build Coastguard Worker             #ifndef Z7_ST
4100*f6dc9357SAndroid Build Coastguard Worker               , &affinityMode
4101*f6dc9357SAndroid Build Coastguard Worker             #endif
4102*f6dc9357SAndroid Build Coastguard Worker             );
4103*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
4104*f6dc9357SAndroid Build Coastguard Worker 
4105*f6dc9357SAndroid Build Coastguard Worker         if (freqCallback)
4106*f6dc9357SAndroid Build Coastguard Worker         {
4107*f6dc9357SAndroid Build Coastguard Worker           RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes))
4108*f6dc9357SAndroid Build Coastguard Worker         }
4109*f6dc9357SAndroid Build Coastguard Worker 
4110*f6dc9357SAndroid Build Coastguard Worker         if (printCallback)
4111*f6dc9357SAndroid Build Coastguard Worker         {
4112*f6dc9357SAndroid Build Coastguard Worker           /*
4113*f6dc9357SAndroid Build Coastguard Worker           if (realDelta == 0)
4114*f6dc9357SAndroid Build Coastguard Worker           {
4115*f6dc9357SAndroid Build Coastguard Worker             printCallback->Print(" -");
4116*f6dc9357SAndroid Build Coastguard Worker           }
4117*f6dc9357SAndroid Build Coastguard Worker           else
4118*f6dc9357SAndroid Build Coastguard Worker           */
4119*f6dc9357SAndroid Build Coastguard Worker           {
4120*f6dc9357SAndroid Build Coastguard Worker             // PrintNumber(*printCallback, start, 0);
4121*f6dc9357SAndroid Build Coastguard Worker             PrintUsage(*printCallback, fb.UsageRes, 3);
4122*f6dc9357SAndroid Build Coastguard Worker             printCallback->Print("%");
4123*f6dc9357SAndroid Build Coastguard Worker             PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0);
4124*f6dc9357SAndroid Build Coastguard Worker             printCallback->Print("  ");
4125*f6dc9357SAndroid Build Coastguard Worker 
4126*f6dc9357SAndroid Build Coastguard Worker             // PrintNumber(*printCallback, fb.UsageRes, 5);
4127*f6dc9357SAndroid Build Coastguard Worker           }
4128*f6dc9357SAndroid Build Coastguard Worker         }
4129*f6dc9357SAndroid Build Coastguard Worker       }
4130*f6dc9357SAndroid Build Coastguard Worker       // if (jj >= 1)
4131*f6dc9357SAndroid Build Coastguard Worker       {
4132*f6dc9357SAndroid Build Coastguard Worker         const bool needStop = (numMilCommands >= (1 <<
4133*f6dc9357SAndroid Build Coastguard Worker           #ifdef _DEBUG
4134*f6dc9357SAndroid Build Coastguard Worker             7
4135*f6dc9357SAndroid Build Coastguard Worker           #else
4136*f6dc9357SAndroid Build Coastguard Worker             11
4137*f6dc9357SAndroid Build Coastguard Worker           #endif
4138*f6dc9357SAndroid Build Coastguard Worker           ));
4139*f6dc9357SAndroid Build Coastguard Worker         if (needStop)
4140*f6dc9357SAndroid Build Coastguard Worker           break;
4141*f6dc9357SAndroid Build Coastguard Worker         numMilCommands <<= 1;
4142*f6dc9357SAndroid Build Coastguard Worker       }
4143*f6dc9357SAndroid Build Coastguard Worker     }
4144*f6dc9357SAndroid Build Coastguard Worker     if (freqCallback)
4145*f6dc9357SAndroid Build Coastguard Worker     {
4146*f6dc9357SAndroid Build Coastguard Worker       RINOK(freqCallback->FreqsFinished(numThreads))
4147*f6dc9357SAndroid Build Coastguard Worker     }
4148*f6dc9357SAndroid Build Coastguard Worker   }
4149*f6dc9357SAndroid Build Coastguard Worker 
4150*f6dc9357SAndroid Build Coastguard Worker 
4151*f6dc9357SAndroid Build Coastguard Worker   if (printCallback)
4152*f6dc9357SAndroid Build Coastguard Worker   {
4153*f6dc9357SAndroid Build Coastguard Worker     printCallback->NewLine();
4154*f6dc9357SAndroid Build Coastguard Worker     printCallback->NewLine();
4155*f6dc9357SAndroid Build Coastguard Worker     PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
4156*f6dc9357SAndroid Build Coastguard Worker     printCallback->Print(GetProcessThreadsInfo(threadsInfo));
4157*f6dc9357SAndroid Build Coastguard Worker     printCallback->NewLine();
4158*f6dc9357SAndroid Build Coastguard Worker   }
4159*f6dc9357SAndroid Build Coastguard Worker 
4160*f6dc9357SAndroid Build Coastguard Worker   if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
4161*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
4162*f6dc9357SAndroid Build Coastguard Worker 
4163*f6dc9357SAndroid Build Coastguard Worker   UInt64 dict = (UInt64)1 << startDicLog;
4164*f6dc9357SAndroid Build Coastguard Worker   const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict));
4165*f6dc9357SAndroid Build Coastguard Worker 
4166*f6dc9357SAndroid Build Coastguard Worker   const unsigned level = method.GetLevel();
4167*f6dc9357SAndroid Build Coastguard Worker 
4168*f6dc9357SAndroid Build Coastguard Worker   AString &methodName = method.MethodName;
4169*f6dc9357SAndroid Build Coastguard Worker   const AString original_MethodName = methodName;
4170*f6dc9357SAndroid Build Coastguard Worker   if (methodName.IsEmpty())
4171*f6dc9357SAndroid Build Coastguard Worker     methodName = "LZMA";
4172*f6dc9357SAndroid Build Coastguard Worker 
4173*f6dc9357SAndroid Build Coastguard Worker   if (benchCallback)
4174*f6dc9357SAndroid Build Coastguard Worker   {
4175*f6dc9357SAndroid Build Coastguard Worker     CBenchProps benchProps;
4176*f6dc9357SAndroid Build Coastguard Worker     benchProps.SetLzmaCompexity();
4177*f6dc9357SAndroid Build Coastguard Worker     const UInt64 dictSize = method.Get_Lzma_DicSize();
4178*f6dc9357SAndroid Build Coastguard Worker 
4179*f6dc9357SAndroid Build Coastguard Worker     size_t uncompressedDataSize;
4180*f6dc9357SAndroid Build Coastguard Worker     if (use_fileData)
4181*f6dc9357SAndroid Build Coastguard Worker     {
4182*f6dc9357SAndroid Build Coastguard Worker       uncompressedDataSize = fileDataBuffer.Size();
4183*f6dc9357SAndroid Build Coastguard Worker     }
4184*f6dc9357SAndroid Build Coastguard Worker     else
4185*f6dc9357SAndroid Build Coastguard Worker     {
4186*f6dc9357SAndroid Build Coastguard Worker       uncompressedDataSize = kAdditionalSize + (size_t)dictSize;
4187*f6dc9357SAndroid Build Coastguard Worker       if (uncompressedDataSize < dictSize)
4188*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
4189*f6dc9357SAndroid Build Coastguard Worker     }
4190*f6dc9357SAndroid Build Coastguard Worker 
4191*f6dc9357SAndroid Build Coastguard Worker     return MethodBench(
4192*f6dc9357SAndroid Build Coastguard Worker         EXTERNAL_CODECS_LOC_VARS
4193*f6dc9357SAndroid Build Coastguard Worker         complexInCommands,
4194*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
4195*f6dc9357SAndroid Build Coastguard Worker         true, numThreadsSpecified,
4196*f6dc9357SAndroid Build Coastguard Worker         &affinityMode,
4197*f6dc9357SAndroid Build Coastguard Worker       #endif
4198*f6dc9357SAndroid Build Coastguard Worker         method,
4199*f6dc9357SAndroid Build Coastguard Worker         uncompressedDataSize, (const Byte *)fileDataBuffer,
4200*f6dc9357SAndroid Build Coastguard Worker         kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
4201*f6dc9357SAndroid Build Coastguard Worker   }
4202*f6dc9357SAndroid Build Coastguard Worker 
4203*f6dc9357SAndroid Build Coastguard Worker   if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
4204*f6dc9357SAndroid Build Coastguard Worker     methodName = "crc32";
4205*f6dc9357SAndroid Build Coastguard Worker 
4206*f6dc9357SAndroid Build Coastguard Worker   CMethodId hashID;
4207*f6dc9357SAndroid Build Coastguard Worker   const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID);
4208*f6dc9357SAndroid Build Coastguard Worker   int codecIndex = -1;
4209*f6dc9357SAndroid Build Coastguard Worker   bool isFilter = false;
4210*f6dc9357SAndroid Build Coastguard Worker   if (!isHashMethod)
4211*f6dc9357SAndroid Build Coastguard Worker   {
4212*f6dc9357SAndroid Build Coastguard Worker     UInt32 numStreams;
4213*f6dc9357SAndroid Build Coastguard Worker     codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName,
4214*f6dc9357SAndroid Build Coastguard Worker         true,  // encode
4215*f6dc9357SAndroid Build Coastguard Worker         hashID, numStreams, isFilter);
4216*f6dc9357SAndroid Build Coastguard Worker     // we can allow non filter for BW tests
4217*f6dc9357SAndroid Build Coastguard Worker     if (!isFilter) codecIndex = -1;
4218*f6dc9357SAndroid Build Coastguard Worker   }
4219*f6dc9357SAndroid Build Coastguard Worker 
4220*f6dc9357SAndroid Build Coastguard Worker   CBenchCallbackToPrint callback;
4221*f6dc9357SAndroid Build Coastguard Worker   callback.Init();
4222*f6dc9357SAndroid Build Coastguard Worker   callback._file = printCallback;
4223*f6dc9357SAndroid Build Coastguard Worker 
4224*f6dc9357SAndroid Build Coastguard Worker   if (isHashMethod || codecIndex != -1)
4225*f6dc9357SAndroid Build Coastguard Worker   {
4226*f6dc9357SAndroid Build Coastguard Worker     if (!printCallback)
4227*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
4228*f6dc9357SAndroid Build Coastguard Worker     IBenchPrintCallback &f = *printCallback;
4229*f6dc9357SAndroid Build Coastguard Worker 
4230*f6dc9357SAndroid Build Coastguard Worker     UInt64 dict64 = dict;
4231*f6dc9357SAndroid Build Coastguard Worker     if (!dictIsDefined)
4232*f6dc9357SAndroid Build Coastguard Worker       dict64 = (1 << 27);
4233*f6dc9357SAndroid Build Coastguard Worker     if (use_fileData)
4234*f6dc9357SAndroid Build Coastguard Worker     {
4235*f6dc9357SAndroid Build Coastguard Worker       if (!dictIsDefined)
4236*f6dc9357SAndroid Build Coastguard Worker         dict64 = fileDataBuffer.Size();
4237*f6dc9357SAndroid Build Coastguard Worker       else if (dict64 > fileDataBuffer.Size())
4238*f6dc9357SAndroid Build Coastguard Worker         dict64 = fileDataBuffer.Size();
4239*f6dc9357SAndroid Build Coastguard Worker     }
4240*f6dc9357SAndroid Build Coastguard Worker 
4241*f6dc9357SAndroid Build Coastguard Worker     for (;;)
4242*f6dc9357SAndroid Build Coastguard Worker     {
4243*f6dc9357SAndroid Build Coastguard Worker       const int index = method.FindProp(NCoderPropID::kDictionarySize);
4244*f6dc9357SAndroid Build Coastguard Worker       if (index < 0)
4245*f6dc9357SAndroid Build Coastguard Worker         break;
4246*f6dc9357SAndroid Build Coastguard Worker       method.Props.Delete((unsigned)index);
4247*f6dc9357SAndroid Build Coastguard Worker     }
4248*f6dc9357SAndroid Build Coastguard Worker 
4249*f6dc9357SAndroid Build Coastguard Worker     // methodName.RemoveChar(L'-');
4250*f6dc9357SAndroid Build Coastguard Worker     Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method
4251*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *checkSum = NULL;
4252*f6dc9357SAndroid Build Coastguard Worker     int benchIndex = -1;
4253*f6dc9357SAndroid Build Coastguard Worker 
4254*f6dc9357SAndroid Build Coastguard Worker     if (isHashMethod)
4255*f6dc9357SAndroid Build Coastguard Worker     {
4256*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++)
4257*f6dc9357SAndroid Build Coastguard Worker       {
4258*f6dc9357SAndroid Build Coastguard Worker         const CBenchHash &h = g_Hash[i];
4259*f6dc9357SAndroid Build Coastguard Worker         AString benchMethod (h.Name);
4260*f6dc9357SAndroid Build Coastguard Worker         AString benchProps;
4261*f6dc9357SAndroid Build Coastguard Worker         const int propPos = benchMethod.Find(':');
4262*f6dc9357SAndroid Build Coastguard Worker         if (propPos >= 0)
4263*f6dc9357SAndroid Build Coastguard Worker         {
4264*f6dc9357SAndroid Build Coastguard Worker           benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4265*f6dc9357SAndroid Build Coastguard Worker           benchMethod.DeleteFrom((unsigned)propPos);
4266*f6dc9357SAndroid Build Coastguard Worker         }
4267*f6dc9357SAndroid Build Coastguard Worker 
4268*f6dc9357SAndroid Build Coastguard Worker         if (AreSameMethodNames(benchMethod, methodName))
4269*f6dc9357SAndroid Build Coastguard Worker         {
4270*f6dc9357SAndroid Build Coastguard Worker           const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
4271*f6dc9357SAndroid Build Coastguard Worker           /*
4272*f6dc9357SAndroid Build Coastguard Worker           bool isMainMethod = method.PropsString.IsEmpty();
4273*f6dc9357SAndroid Build Coastguard Worker           if (isMainMethod)
4274*f6dc9357SAndroid Build Coastguard Worker             isMainMethod = !checkSum
4275*f6dc9357SAndroid Build Coastguard Worker                 || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8"));
4276*f6dc9357SAndroid Build Coastguard Worker           if (sameProps || isMainMethod)
4277*f6dc9357SAndroid Build Coastguard Worker           */
4278*f6dc9357SAndroid Build Coastguard Worker           {
4279*f6dc9357SAndroid Build Coastguard Worker             complexity = (Int32)h.Complex;
4280*f6dc9357SAndroid Build Coastguard Worker             checkSum = &h.CheckSum;
4281*f6dc9357SAndroid Build Coastguard Worker             if (sameProps)
4282*f6dc9357SAndroid Build Coastguard Worker               break;
4283*f6dc9357SAndroid Build Coastguard Worker             /*
4284*f6dc9357SAndroid Build Coastguard Worker             if property. is not specified, we use the complexity
4285*f6dc9357SAndroid Build Coastguard Worker             for latest fastest method (crc32:64)
4286*f6dc9357SAndroid Build Coastguard Worker             */
4287*f6dc9357SAndroid Build Coastguard Worker           }
4288*f6dc9357SAndroid Build Coastguard Worker         }
4289*f6dc9357SAndroid Build Coastguard Worker       }
4290*f6dc9357SAndroid Build Coastguard Worker       // if (!checkSum) return E_NOTIMPL;
4291*f6dc9357SAndroid Build Coastguard Worker     }
4292*f6dc9357SAndroid Build Coastguard Worker     else
4293*f6dc9357SAndroid Build Coastguard Worker     {
4294*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
4295*f6dc9357SAndroid Build Coastguard Worker       {
4296*f6dc9357SAndroid Build Coastguard Worker         const CBenchMethod &bench = g_Bench[i];
4297*f6dc9357SAndroid Build Coastguard Worker         AString benchMethod (bench.Name);
4298*f6dc9357SAndroid Build Coastguard Worker         AString benchProps;
4299*f6dc9357SAndroid Build Coastguard Worker         const int propPos = benchMethod.Find(':');
4300*f6dc9357SAndroid Build Coastguard Worker         if (propPos >= 0)
4301*f6dc9357SAndroid Build Coastguard Worker         {
4302*f6dc9357SAndroid Build Coastguard Worker           benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4303*f6dc9357SAndroid Build Coastguard Worker           benchMethod.DeleteFrom((unsigned)propPos);
4304*f6dc9357SAndroid Build Coastguard Worker         }
4305*f6dc9357SAndroid Build Coastguard Worker 
4306*f6dc9357SAndroid Build Coastguard Worker         if (AreSameMethodNames(benchMethod, methodName))
4307*f6dc9357SAndroid Build Coastguard Worker         {
4308*f6dc9357SAndroid Build Coastguard Worker           const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps);
4309*f6dc9357SAndroid Build Coastguard Worker           // bool isMainMethod = method.PropsString.IsEmpty();
4310*f6dc9357SAndroid Build Coastguard Worker           // if (sameProps || isMainMethod)
4311*f6dc9357SAndroid Build Coastguard Worker           {
4312*f6dc9357SAndroid Build Coastguard Worker             benchIndex = (int)i;
4313*f6dc9357SAndroid Build Coastguard Worker             if (sameProps)
4314*f6dc9357SAndroid Build Coastguard Worker               break;
4315*f6dc9357SAndroid Build Coastguard Worker           }
4316*f6dc9357SAndroid Build Coastguard Worker         }
4317*f6dc9357SAndroid Build Coastguard Worker       }
4318*f6dc9357SAndroid Build Coastguard Worker       // if (benchIndex < 0) return E_NOTIMPL;
4319*f6dc9357SAndroid Build Coastguard Worker     }
4320*f6dc9357SAndroid Build Coastguard Worker 
4321*f6dc9357SAndroid Build Coastguard Worker     {
4322*f6dc9357SAndroid Build Coastguard Worker       /* we count usage only for crc and filter. non-filters are not supported */
4323*f6dc9357SAndroid Build Coastguard Worker       UInt64 usage = (1 << 20);
4324*f6dc9357SAndroid Build Coastguard Worker       UInt64 bufSize = dict64;
4325*f6dc9357SAndroid Build Coastguard Worker       UInt32 numBlocks = isHashMethod ? 1 : 3;
4326*f6dc9357SAndroid Build Coastguard Worker       if (use_fileData)
4327*f6dc9357SAndroid Build Coastguard Worker       {
4328*f6dc9357SAndroid Build Coastguard Worker         usage += fileDataBuffer.Size();
4329*f6dc9357SAndroid Build Coastguard Worker         if (bufSize > fileDataBuffer.Size())
4330*f6dc9357SAndroid Build Coastguard Worker           bufSize = fileDataBuffer.Size();
4331*f6dc9357SAndroid Build Coastguard Worker         if (isHashMethod)
4332*f6dc9357SAndroid Build Coastguard Worker         {
4333*f6dc9357SAndroid Build Coastguard Worker           numBlocks = 0;
4334*f6dc9357SAndroid Build Coastguard Worker           #ifndef Z7_ST
4335*f6dc9357SAndroid Build Coastguard Worker           if (numThreadsSpecified != 1)
4336*f6dc9357SAndroid Build Coastguard Worker             numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0);
4337*f6dc9357SAndroid Build Coastguard Worker           #endif
4338*f6dc9357SAndroid Build Coastguard Worker         }
4339*f6dc9357SAndroid Build Coastguard Worker       }
4340*f6dc9357SAndroid Build Coastguard Worker       usage += numThreadsSpecified * bufSize * numBlocks;
4341*f6dc9357SAndroid Build Coastguard Worker       Print_Usage_and_Threads(f, usage, numThreadsSpecified);
4342*f6dc9357SAndroid Build Coastguard Worker     }
4343*f6dc9357SAndroid Build Coastguard Worker 
4344*f6dc9357SAndroid Build Coastguard Worker     CUIntVector numThreadsVector;
4345*f6dc9357SAndroid Build Coastguard Worker     {
4346*f6dc9357SAndroid Build Coastguard Worker       unsigned nt = numThreads_Start;
4347*f6dc9357SAndroid Build Coastguard Worker       for (;;)
4348*f6dc9357SAndroid Build Coastguard Worker       {
4349*f6dc9357SAndroid Build Coastguard Worker         if (nt > numThreadsSpecified)
4350*f6dc9357SAndroid Build Coastguard Worker           break;
4351*f6dc9357SAndroid Build Coastguard Worker         numThreadsVector.Add(nt);
4352*f6dc9357SAndroid Build Coastguard Worker         const unsigned next = nt * 2;
4353*f6dc9357SAndroid Build Coastguard Worker         const UInt32 ntHalf= numThreadsSpecified / 2;
4354*f6dc9357SAndroid Build Coastguard Worker         if (ntHalf > nt && ntHalf < next)
4355*f6dc9357SAndroid Build Coastguard Worker           numThreadsVector.Add(ntHalf);
4356*f6dc9357SAndroid Build Coastguard Worker         if (numThreadsSpecified > nt && numThreadsSpecified < next)
4357*f6dc9357SAndroid Build Coastguard Worker           numThreadsVector.Add(numThreadsSpecified);
4358*f6dc9357SAndroid Build Coastguard Worker         nt = next;
4359*f6dc9357SAndroid Build Coastguard Worker       }
4360*f6dc9357SAndroid Build Coastguard Worker     }
4361*f6dc9357SAndroid Build Coastguard Worker 
4362*f6dc9357SAndroid Build Coastguard Worker     unsigned numColumns = isHashMethod ? 1 : 2;
4363*f6dc9357SAndroid Build Coastguard Worker     CTempValues speedTotals;
4364*f6dc9357SAndroid Build Coastguard Worker     CTempValues usageTotals;
4365*f6dc9357SAndroid Build Coastguard Worker     {
4366*f6dc9357SAndroid Build Coastguard Worker       const unsigned numItems = numThreadsVector.Size() * numColumns;
4367*f6dc9357SAndroid Build Coastguard Worker       speedTotals.Alloc(numItems);
4368*f6dc9357SAndroid Build Coastguard Worker       usageTotals.Alloc(numItems);
4369*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < numItems; i++)
4370*f6dc9357SAndroid Build Coastguard Worker       {
4371*f6dc9357SAndroid Build Coastguard Worker         speedTotals.Values[i] = 0;
4372*f6dc9357SAndroid Build Coastguard Worker         usageTotals.Values[i] = 0;
4373*f6dc9357SAndroid Build Coastguard Worker       }
4374*f6dc9357SAndroid Build Coastguard Worker     }
4375*f6dc9357SAndroid Build Coastguard Worker 
4376*f6dc9357SAndroid Build Coastguard Worker     f.NewLine();
4377*f6dc9357SAndroid Build Coastguard Worker     for (unsigned line = 0; line < 3; line++)
4378*f6dc9357SAndroid Build Coastguard Worker     {
4379*f6dc9357SAndroid Build Coastguard Worker       f.NewLine();
4380*f6dc9357SAndroid Build Coastguard Worker       f.Print(line == 0 ? "THRD" : line == 1 ? "    " : "Size");
4381*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (ti, numThreadsVector)
4382*f6dc9357SAndroid Build Coastguard Worker       {
4383*f6dc9357SAndroid Build Coastguard Worker         if (ti != 0)
4384*f6dc9357SAndroid Build Coastguard Worker           Print_Delimiter(f);
4385*f6dc9357SAndroid Build Coastguard Worker         if (line == 0)
4386*f6dc9357SAndroid Build Coastguard Worker         {
4387*f6dc9357SAndroid Build Coastguard Worker           PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1));
4388*f6dc9357SAndroid Build Coastguard Worker           PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed);
4389*f6dc9357SAndroid Build Coastguard Worker         }
4390*f6dc9357SAndroid Build Coastguard Worker         else
4391*f6dc9357SAndroid Build Coastguard Worker         {
4392*f6dc9357SAndroid Build Coastguard Worker           for (unsigned c = 0; c < numColumns; c++)
4393*f6dc9357SAndroid Build Coastguard Worker           {
4394*f6dc9357SAndroid Build Coastguard Worker             PrintRight(f, line == 1 ? "Usage" : "%",    kFieldSize_Usage + 1);
4395*f6dc9357SAndroid Build Coastguard Worker             PrintRight(f, line == 1 ? "BW"    : "MB/s", kFieldSize_CrcSpeed + 1);
4396*f6dc9357SAndroid Build Coastguard Worker           }
4397*f6dc9357SAndroid Build Coastguard Worker         }
4398*f6dc9357SAndroid Build Coastguard Worker       }
4399*f6dc9357SAndroid Build Coastguard Worker     }
4400*f6dc9357SAndroid Build Coastguard Worker     f.NewLine();
4401*f6dc9357SAndroid Build Coastguard Worker 
4402*f6dc9357SAndroid Build Coastguard Worker     UInt64 numSteps = 0;
4403*f6dc9357SAndroid Build Coastguard Worker 
4404*f6dc9357SAndroid Build Coastguard Worker     // for (UInt32 iter = 0; iter < numIterations; iter++)
4405*f6dc9357SAndroid Build Coastguard Worker     // {
4406*f6dc9357SAndroid Build Coastguard Worker     unsigned pow = 10; // kNumHashDictBits
4407*f6dc9357SAndroid Build Coastguard Worker     if (startDicLog_Defined)
4408*f6dc9357SAndroid Build Coastguard Worker       pow = startDicLog;
4409*f6dc9357SAndroid Build Coastguard Worker 
4410*f6dc9357SAndroid Build Coastguard Worker     // #define NUM_SUB_BITS 2
4411*f6dc9357SAndroid Build Coastguard Worker     // pow <<= NUM_SUB_BITS;
4412*f6dc9357SAndroid Build Coastguard Worker     for (;; pow++)
4413*f6dc9357SAndroid Build Coastguard Worker     {
4414*f6dc9357SAndroid Build Coastguard Worker       const UInt64 bufSize = (UInt64)1 << pow;
4415*f6dc9357SAndroid Build Coastguard Worker       // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS);
4416*f6dc9357SAndroid Build Coastguard Worker       // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS);
4417*f6dc9357SAndroid Build Coastguard Worker 
4418*f6dc9357SAndroid Build Coastguard Worker       size_t dataSize = fileDataBuffer.Size();
4419*f6dc9357SAndroid Build Coastguard Worker       if (dataSize > bufSize || !use_fileData)
4420*f6dc9357SAndroid Build Coastguard Worker         dataSize = (size_t)bufSize;
4421*f6dc9357SAndroid Build Coastguard Worker 
4422*f6dc9357SAndroid Build Coastguard Worker       for (UInt32 iter = 0; iter < numIterations; iter++)
4423*f6dc9357SAndroid Build Coastguard Worker       {
4424*f6dc9357SAndroid Build Coastguard Worker         Print_Pow(f, pow);
4425*f6dc9357SAndroid Build Coastguard Worker         // PrintNumber(f, bufSize >> 10, 4);
4426*f6dc9357SAndroid Build Coastguard Worker 
4427*f6dc9357SAndroid Build Coastguard Worker         FOR_VECTOR (ti, numThreadsVector)
4428*f6dc9357SAndroid Build Coastguard Worker         {
4429*f6dc9357SAndroid Build Coastguard Worker           RINOK(f.CheckBreak())
4430*f6dc9357SAndroid Build Coastguard Worker           const UInt32 numThreads = numThreadsVector[ti];
4431*f6dc9357SAndroid Build Coastguard Worker           if (isHashMethod)
4432*f6dc9357SAndroid Build Coastguard Worker           {
4433*f6dc9357SAndroid Build Coastguard Worker             UInt64 speed = 0;
4434*f6dc9357SAndroid Build Coastguard Worker             UInt64 usage = 0;
4435*f6dc9357SAndroid Build Coastguard Worker             const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
4436*f6dc9357SAndroid Build Coastguard Worker               numThreads,
4437*f6dc9357SAndroid Build Coastguard Worker               dataSize, (const Byte *)fileDataBuffer,
4438*f6dc9357SAndroid Build Coastguard Worker               speed, usage,
4439*f6dc9357SAndroid Build Coastguard Worker               (UInt32)complexity,
4440*f6dc9357SAndroid Build Coastguard Worker               1, // benchWeight,
4441*f6dc9357SAndroid Build Coastguard Worker               (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL,
4442*f6dc9357SAndroid Build Coastguard Worker               method,
4443*f6dc9357SAndroid Build Coastguard Worker               &f,
4444*f6dc9357SAndroid Build Coastguard Worker             #ifndef Z7_ST
4445*f6dc9357SAndroid Build Coastguard Worker               &affinityMode,
4446*f6dc9357SAndroid Build Coastguard Worker             #endif
4447*f6dc9357SAndroid Build Coastguard Worker               false, // showRating
4448*f6dc9357SAndroid Build Coastguard Worker               NULL, false, 0);
4449*f6dc9357SAndroid Build Coastguard Worker             RINOK(res)
4450*f6dc9357SAndroid Build Coastguard Worker 
4451*f6dc9357SAndroid Build Coastguard Worker             if (ti != 0)
4452*f6dc9357SAndroid Build Coastguard Worker               Print_Delimiter(f);
4453*f6dc9357SAndroid Build Coastguard Worker 
4454*f6dc9357SAndroid Build Coastguard Worker             Bench_BW_Print_Usage_Speed(f, usage, speed);
4455*f6dc9357SAndroid Build Coastguard Worker             speedTotals.Values[ti] += speed;
4456*f6dc9357SAndroid Build Coastguard Worker             usageTotals.Values[ti] += usage;
4457*f6dc9357SAndroid Build Coastguard Worker           }
4458*f6dc9357SAndroid Build Coastguard Worker           else
4459*f6dc9357SAndroid Build Coastguard Worker           {
4460*f6dc9357SAndroid Build Coastguard Worker             {
4461*f6dc9357SAndroid Build Coastguard Worker               unsigned keySize = 32;
4462*f6dc9357SAndroid Build Coastguard Worker                    if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16;
4463*f6dc9357SAndroid Build Coastguard Worker               else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24;
4464*f6dc9357SAndroid Build Coastguard Worker               callback.BenchProps.KeySize = keySize;
4465*f6dc9357SAndroid Build Coastguard Worker             }
4466*f6dc9357SAndroid Build Coastguard Worker 
4467*f6dc9357SAndroid Build Coastguard Worker             COneMethodInfo method2 = method;
4468*f6dc9357SAndroid Build Coastguard Worker             unsigned bench_DictBits;
4469*f6dc9357SAndroid Build Coastguard Worker 
4470*f6dc9357SAndroid Build Coastguard Worker             if (benchIndex >= 0)
4471*f6dc9357SAndroid Build Coastguard Worker             {
4472*f6dc9357SAndroid Build Coastguard Worker               const CBenchMethod &bench = g_Bench[benchIndex];
4473*f6dc9357SAndroid Build Coastguard Worker               callback.BenchProps.EncComplex = bench.EncComplex;
4474*f6dc9357SAndroid Build Coastguard Worker               callback.BenchProps.DecComplexUnc = bench.DecComplexUnc;
4475*f6dc9357SAndroid Build Coastguard Worker               callback.BenchProps.DecComplexCompr = bench.DecComplexCompr;
4476*f6dc9357SAndroid Build Coastguard Worker               bench_DictBits = bench.DictBits;
4477*f6dc9357SAndroid Build Coastguard Worker               // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug
4478*f6dc9357SAndroid Build Coastguard Worker             }
4479*f6dc9357SAndroid Build Coastguard Worker             else
4480*f6dc9357SAndroid Build Coastguard Worker             {
4481*f6dc9357SAndroid Build Coastguard Worker               bench_DictBits = kOldLzmaDictBits; // = 32 default
4482*f6dc9357SAndroid Build Coastguard Worker               if (isFilter)
4483*f6dc9357SAndroid Build Coastguard Worker               {
4484*f6dc9357SAndroid Build Coastguard Worker                 const unsigned k_UnknownCoderComplexity = 4;
4485*f6dc9357SAndroid Build Coastguard Worker                 callback.BenchProps.EncComplex = k_UnknownCoderComplexity;
4486*f6dc9357SAndroid Build Coastguard Worker                 callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity;
4487*f6dc9357SAndroid Build Coastguard Worker               }
4488*f6dc9357SAndroid Build Coastguard Worker               else
4489*f6dc9357SAndroid Build Coastguard Worker               {
4490*f6dc9357SAndroid Build Coastguard Worker                 callback.BenchProps.EncComplex = 1 << 10;
4491*f6dc9357SAndroid Build Coastguard Worker                 callback.BenchProps.DecComplexUnc = 1 << 6;
4492*f6dc9357SAndroid Build Coastguard Worker               }
4493*f6dc9357SAndroid Build Coastguard Worker               callback.BenchProps.DecComplexCompr = 0;
4494*f6dc9357SAndroid Build Coastguard Worker             }
4495*f6dc9357SAndroid Build Coastguard Worker             callback.NeedPrint = false;
4496*f6dc9357SAndroid Build Coastguard Worker 
4497*f6dc9357SAndroid Build Coastguard Worker             if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
4498*f6dc9357SAndroid Build Coastguard Worker             {
4499*f6dc9357SAndroid Build Coastguard Worker               const NCOM::CPropVariant propVariant = (UInt32)pow;
4500*f6dc9357SAndroid Build Coastguard Worker               RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
4501*f6dc9357SAndroid Build Coastguard Worker             }
4502*f6dc9357SAndroid Build Coastguard Worker 
4503*f6dc9357SAndroid Build Coastguard Worker             const HRESULT res = MethodBench(
4504*f6dc9357SAndroid Build Coastguard Worker                 EXTERNAL_CODECS_LOC_VARS
4505*f6dc9357SAndroid Build Coastguard Worker                 complexInCommands,
4506*f6dc9357SAndroid Build Coastguard Worker               #ifndef Z7_ST
4507*f6dc9357SAndroid Build Coastguard Worker                 false, // oldLzmaBenchMode
4508*f6dc9357SAndroid Build Coastguard Worker                 numThreadsVector[ti],
4509*f6dc9357SAndroid Build Coastguard Worker                 &affinityMode,
4510*f6dc9357SAndroid Build Coastguard Worker               #endif
4511*f6dc9357SAndroid Build Coastguard Worker                 method2,
4512*f6dc9357SAndroid Build Coastguard Worker                 dataSize, (const Byte *)fileDataBuffer,
4513*f6dc9357SAndroid Build Coastguard Worker                 bench_DictBits,
4514*f6dc9357SAndroid Build Coastguard Worker                 printCallback,
4515*f6dc9357SAndroid Build Coastguard Worker                 &callback,
4516*f6dc9357SAndroid Build Coastguard Worker                 &callback.BenchProps);
4517*f6dc9357SAndroid Build Coastguard Worker             RINOK(res)
4518*f6dc9357SAndroid Build Coastguard Worker 
4519*f6dc9357SAndroid Build Coastguard Worker             if (ti != 0)
4520*f6dc9357SAndroid Build Coastguard Worker               Print_Delimiter(f);
4521*f6dc9357SAndroid Build Coastguard Worker 
4522*f6dc9357SAndroid Build Coastguard Worker             for (unsigned i = 0; i < 2; i++)
4523*f6dc9357SAndroid Build Coastguard Worker             {
4524*f6dc9357SAndroid Build Coastguard Worker               const CBenchInfo &bi = callback.BenchInfo_Results[i];
4525*f6dc9357SAndroid Build Coastguard Worker               const UInt64 usage = bi.GetUsage();
4526*f6dc9357SAndroid Build Coastguard Worker               const UInt64 speed = bi.GetUnpackSizeSpeed();
4527*f6dc9357SAndroid Build Coastguard Worker               usageTotals.Values[ti * 2 + i] += usage;
4528*f6dc9357SAndroid Build Coastguard Worker               speedTotals.Values[ti * 2 + i] += speed;
4529*f6dc9357SAndroid Build Coastguard Worker               Bench_BW_Print_Usage_Speed(f, usage, speed);
4530*f6dc9357SAndroid Build Coastguard Worker             }
4531*f6dc9357SAndroid Build Coastguard Worker           }
4532*f6dc9357SAndroid Build Coastguard Worker         }
4533*f6dc9357SAndroid Build Coastguard Worker 
4534*f6dc9357SAndroid Build Coastguard Worker         f.NewLine();
4535*f6dc9357SAndroid Build Coastguard Worker         numSteps++;
4536*f6dc9357SAndroid Build Coastguard Worker       }
4537*f6dc9357SAndroid Build Coastguard Worker       if (dataSize >= dict64)
4538*f6dc9357SAndroid Build Coastguard Worker         break;
4539*f6dc9357SAndroid Build Coastguard Worker     }
4540*f6dc9357SAndroid Build Coastguard Worker 
4541*f6dc9357SAndroid Build Coastguard Worker     if (numSteps != 0)
4542*f6dc9357SAndroid Build Coastguard Worker     {
4543*f6dc9357SAndroid Build Coastguard Worker       f.Print("Avg:");
4544*f6dc9357SAndroid Build Coastguard Worker       for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++)
4545*f6dc9357SAndroid Build Coastguard Worker       {
4546*f6dc9357SAndroid Build Coastguard Worker         if (ti != 0)
4547*f6dc9357SAndroid Build Coastguard Worker           Print_Delimiter(f);
4548*f6dc9357SAndroid Build Coastguard Worker         for (unsigned i = 0; i < numColumns; i++)
4549*f6dc9357SAndroid Build Coastguard Worker           Bench_BW_Print_Usage_Speed(f,
4550*f6dc9357SAndroid Build Coastguard Worker               usageTotals.Values[ti * numColumns + i] / numSteps,
4551*f6dc9357SAndroid Build Coastguard Worker               speedTotals.Values[ti * numColumns + i] / numSteps);
4552*f6dc9357SAndroid Build Coastguard Worker       }
4553*f6dc9357SAndroid Build Coastguard Worker       f.NewLine();
4554*f6dc9357SAndroid Build Coastguard Worker     }
4555*f6dc9357SAndroid Build Coastguard Worker 
4556*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
4557*f6dc9357SAndroid Build Coastguard Worker   }
4558*f6dc9357SAndroid Build Coastguard Worker 
4559*f6dc9357SAndroid Build Coastguard Worker   bool use2Columns = false;
4560*f6dc9357SAndroid Build Coastguard Worker 
4561*f6dc9357SAndroid Build Coastguard Worker   bool totalBenchMode = false;
4562*f6dc9357SAndroid Build Coastguard Worker   bool onlyHashBench = false;
4563*f6dc9357SAndroid Build Coastguard Worker   if (methodName.IsEqualTo_Ascii_NoCase("hash"))
4564*f6dc9357SAndroid Build Coastguard Worker   {
4565*f6dc9357SAndroid Build Coastguard Worker     onlyHashBench = true;
4566*f6dc9357SAndroid Build Coastguard Worker     methodName = "*";
4567*f6dc9357SAndroid Build Coastguard Worker     totalBenchMode = true;
4568*f6dc9357SAndroid Build Coastguard Worker   }
4569*f6dc9357SAndroid Build Coastguard Worker   else if (methodName.Find('*') >= 0)
4570*f6dc9357SAndroid Build Coastguard Worker     totalBenchMode = true;
4571*f6dc9357SAndroid Build Coastguard Worker 
4572*f6dc9357SAndroid Build Coastguard Worker   // ---------- Threads loop ----------
4573*f6dc9357SAndroid Build Coastguard Worker   for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++)
4574*f6dc9357SAndroid Build Coastguard Worker   {
4575*f6dc9357SAndroid Build Coastguard Worker 
4576*f6dc9357SAndroid Build Coastguard Worker   UInt32 numThreads = numThreadsSpecified;
4577*f6dc9357SAndroid Build Coastguard Worker 
4578*f6dc9357SAndroid Build Coastguard Worker   if (!multiThreadTests)
4579*f6dc9357SAndroid Build Coastguard Worker   {
4580*f6dc9357SAndroid Build Coastguard Worker     if (threadsPassIndex != 0)
4581*f6dc9357SAndroid Build Coastguard Worker       break;
4582*f6dc9357SAndroid Build Coastguard Worker   }
4583*f6dc9357SAndroid Build Coastguard Worker   else
4584*f6dc9357SAndroid Build Coastguard Worker   {
4585*f6dc9357SAndroid Build Coastguard Worker     numThreads = 1;
4586*f6dc9357SAndroid Build Coastguard Worker     if (threadsPassIndex != 0)
4587*f6dc9357SAndroid Build Coastguard Worker     {
4588*f6dc9357SAndroid Build Coastguard Worker       if (numCPUs < 2)
4589*f6dc9357SAndroid Build Coastguard Worker         break;
4590*f6dc9357SAndroid Build Coastguard Worker       numThreads = numCPUs;
4591*f6dc9357SAndroid Build Coastguard Worker       if (threadsPassIndex == 1)
4592*f6dc9357SAndroid Build Coastguard Worker       {
4593*f6dc9357SAndroid Build Coastguard Worker         if (numCPUs >= 4)
4594*f6dc9357SAndroid Build Coastguard Worker           numThreads = numCPUs / 2;
4595*f6dc9357SAndroid Build Coastguard Worker       }
4596*f6dc9357SAndroid Build Coastguard Worker       else if (numCPUs < 4)
4597*f6dc9357SAndroid Build Coastguard Worker         break;
4598*f6dc9357SAndroid Build Coastguard Worker     }
4599*f6dc9357SAndroid Build Coastguard Worker   }
4600*f6dc9357SAndroid Build Coastguard Worker 
4601*f6dc9357SAndroid Build Coastguard Worker   IBenchPrintCallback &f = *printCallback;
4602*f6dc9357SAndroid Build Coastguard Worker 
4603*f6dc9357SAndroid Build Coastguard Worker   if (threadsPassIndex > 0)
4604*f6dc9357SAndroid Build Coastguard Worker   {
4605*f6dc9357SAndroid Build Coastguard Worker     f.NewLine();
4606*f6dc9357SAndroid Build Coastguard Worker     f.NewLine();
4607*f6dc9357SAndroid Build Coastguard Worker   }
4608*f6dc9357SAndroid Build Coastguard Worker 
4609*f6dc9357SAndroid Build Coastguard Worker   if (!dictIsDefined && !onlyHashBench)
4610*f6dc9357SAndroid Build Coastguard Worker   {
4611*f6dc9357SAndroid Build Coastguard Worker     // we use dicSizeLog and dicSizeLog_Main for data size.
4612*f6dc9357SAndroid Build Coastguard Worker     // also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize.
4613*f6dc9357SAndroid Build Coastguard Worker     const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
4614*f6dc9357SAndroid Build Coastguard Worker     unsigned dicSizeLog = dicSizeLog_Main;
4615*f6dc9357SAndroid Build Coastguard Worker 
4616*f6dc9357SAndroid Build Coastguard Worker     #ifdef UNDER_CE
4617*f6dc9357SAndroid Build Coastguard Worker     dicSizeLog = (UInt64)1 << 20;
4618*f6dc9357SAndroid Build Coastguard Worker     #endif
4619*f6dc9357SAndroid Build Coastguard Worker 
4620*f6dc9357SAndroid Build Coastguard Worker     if (ramSize_Defined)
4621*f6dc9357SAndroid Build Coastguard Worker     for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
4622*f6dc9357SAndroid Build Coastguard Worker       if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
4623*f6dc9357SAndroid Build Coastguard Worker         break;
4624*f6dc9357SAndroid Build Coastguard Worker 
4625*f6dc9357SAndroid Build Coastguard Worker     dict = (UInt64)1 << dicSizeLog;
4626*f6dc9357SAndroid Build Coastguard Worker 
4627*f6dc9357SAndroid Build Coastguard Worker     if (totalBenchMode && dicSizeLog != dicSizeLog_Main)
4628*f6dc9357SAndroid Build Coastguard Worker     {
4629*f6dc9357SAndroid Build Coastguard Worker       f.Print("Dictionary reduced to: ");
4630*f6dc9357SAndroid Build Coastguard Worker       PrintNumber(f, dicSizeLog, 1);
4631*f6dc9357SAndroid Build Coastguard Worker       f.NewLine();
4632*f6dc9357SAndroid Build Coastguard Worker     }
4633*f6dc9357SAndroid Build Coastguard Worker   }
4634*f6dc9357SAndroid Build Coastguard Worker 
4635*f6dc9357SAndroid Build Coastguard Worker   Print_Usage_and_Threads(f,
4636*f6dc9357SAndroid Build Coastguard Worker       onlyHashBench ?
4637*f6dc9357SAndroid Build Coastguard Worker         GetBenchMemoryUsage_Hash(numThreads, dict) :
4638*f6dc9357SAndroid Build Coastguard Worker         GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode),
4639*f6dc9357SAndroid Build Coastguard Worker       numThreads);
4640*f6dc9357SAndroid Build Coastguard Worker 
4641*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4642*f6dc9357SAndroid Build Coastguard Worker 
4643*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4644*f6dc9357SAndroid Build Coastguard Worker 
4645*f6dc9357SAndroid Build Coastguard Worker   if (totalBenchMode)
4646*f6dc9357SAndroid Build Coastguard Worker   {
4647*f6dc9357SAndroid Build Coastguard Worker     callback.NameFieldSize = kFieldSize_Name;
4648*f6dc9357SAndroid Build Coastguard Worker     use2Columns = false;
4649*f6dc9357SAndroid Build Coastguard Worker   }
4650*f6dc9357SAndroid Build Coastguard Worker   else
4651*f6dc9357SAndroid Build Coastguard Worker   {
4652*f6dc9357SAndroid Build Coastguard Worker     callback.NameFieldSize = kFieldSize_SmallName;
4653*f6dc9357SAndroid Build Coastguard Worker     use2Columns = true;
4654*f6dc9357SAndroid Build Coastguard Worker   }
4655*f6dc9357SAndroid Build Coastguard Worker   callback.Use2Columns = use2Columns;
4656*f6dc9357SAndroid Build Coastguard Worker 
4657*f6dc9357SAndroid Build Coastguard Worker   bool showFreq = false;
4658*f6dc9357SAndroid Build Coastguard Worker   UInt64 cpuFreq = 0;
4659*f6dc9357SAndroid Build Coastguard Worker 
4660*f6dc9357SAndroid Build Coastguard Worker   if (totalBenchMode)
4661*f6dc9357SAndroid Build Coastguard Worker   {
4662*f6dc9357SAndroid Build Coastguard Worker     showFreq = true;
4663*f6dc9357SAndroid Build Coastguard Worker   }
4664*f6dc9357SAndroid Build Coastguard Worker 
4665*f6dc9357SAndroid Build Coastguard Worker   unsigned fileldSize = kFieldSize_TotalSize;
4666*f6dc9357SAndroid Build Coastguard Worker   if (showFreq)
4667*f6dc9357SAndroid Build Coastguard Worker     fileldSize += kFieldSize_EUAndEffec;
4668*f6dc9357SAndroid Build Coastguard Worker 
4669*f6dc9357SAndroid Build Coastguard Worker   if (use2Columns)
4670*f6dc9357SAndroid Build Coastguard Worker   {
4671*f6dc9357SAndroid Build Coastguard Worker     PrintSpaces(f, callback.NameFieldSize);
4672*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "Compressing", fileldSize);
4673*f6dc9357SAndroid Build Coastguard Worker     f.Print(kSep);
4674*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "Decompressing", fileldSize);
4675*f6dc9357SAndroid Build Coastguard Worker   }
4676*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4677*f6dc9357SAndroid Build Coastguard Worker   PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize);
4678*f6dc9357SAndroid Build Coastguard Worker 
4679*f6dc9357SAndroid Build Coastguard Worker   int j;
4680*f6dc9357SAndroid Build Coastguard Worker 
4681*f6dc9357SAndroid Build Coastguard Worker   for (j = 0; j < 2; j++)
4682*f6dc9357SAndroid Build Coastguard Worker   {
4683*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "Speed", kFieldSize_Speed + 1);
4684*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "Usage", kFieldSize_Usage + 1);
4685*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "R/U", kFieldSize_RU + 1);
4686*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "Rating", kFieldSize_Rating + 1);
4687*f6dc9357SAndroid Build Coastguard Worker     if (showFreq)
4688*f6dc9357SAndroid Build Coastguard Worker     {
4689*f6dc9357SAndroid Build Coastguard Worker       PrintRight(f, "E/U", kFieldSize_EU + 1);
4690*f6dc9357SAndroid Build Coastguard Worker       PrintRight(f, "Effec", kFieldSize_Effec + 1);
4691*f6dc9357SAndroid Build Coastguard Worker     }
4692*f6dc9357SAndroid Build Coastguard Worker     if (!use2Columns)
4693*f6dc9357SAndroid Build Coastguard Worker       break;
4694*f6dc9357SAndroid Build Coastguard Worker     if (j == 0)
4695*f6dc9357SAndroid Build Coastguard Worker       f.Print(kSep);
4696*f6dc9357SAndroid Build Coastguard Worker   }
4697*f6dc9357SAndroid Build Coastguard Worker 
4698*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4699*f6dc9357SAndroid Build Coastguard Worker   PrintSpaces(f, callback.NameFieldSize);
4700*f6dc9357SAndroid Build Coastguard Worker 
4701*f6dc9357SAndroid Build Coastguard Worker   for (j = 0; j < 2; j++)
4702*f6dc9357SAndroid Build Coastguard Worker   {
4703*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "KiB/s", kFieldSize_Speed + 1);
4704*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "%", kFieldSize_Usage + 1);
4705*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "MIPS", kFieldSize_RU + 1);
4706*f6dc9357SAndroid Build Coastguard Worker     PrintRight(f, "MIPS", kFieldSize_Rating + 1);
4707*f6dc9357SAndroid Build Coastguard Worker     if (showFreq)
4708*f6dc9357SAndroid Build Coastguard Worker     {
4709*f6dc9357SAndroid Build Coastguard Worker       PrintRight(f, "%", kFieldSize_EU + 1);
4710*f6dc9357SAndroid Build Coastguard Worker       PrintRight(f, "%", kFieldSize_Effec + 1);
4711*f6dc9357SAndroid Build Coastguard Worker     }
4712*f6dc9357SAndroid Build Coastguard Worker     if (!use2Columns)
4713*f6dc9357SAndroid Build Coastguard Worker       break;
4714*f6dc9357SAndroid Build Coastguard Worker     if (j == 0)
4715*f6dc9357SAndroid Build Coastguard Worker       f.Print(kSep);
4716*f6dc9357SAndroid Build Coastguard Worker   }
4717*f6dc9357SAndroid Build Coastguard Worker 
4718*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4719*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4720*f6dc9357SAndroid Build Coastguard Worker 
4721*f6dc9357SAndroid Build Coastguard Worker   if (specifiedFreq != 0)
4722*f6dc9357SAndroid Build Coastguard Worker     cpuFreq = specifiedFreq;
4723*f6dc9357SAndroid Build Coastguard Worker 
4724*f6dc9357SAndroid Build Coastguard Worker   // bool showTotalSpeed = false;
4725*f6dc9357SAndroid Build Coastguard Worker 
4726*f6dc9357SAndroid Build Coastguard Worker   if (totalBenchMode)
4727*f6dc9357SAndroid Build Coastguard Worker   {
4728*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < numIterations; i++)
4729*f6dc9357SAndroid Build Coastguard Worker     {
4730*f6dc9357SAndroid Build Coastguard Worker       if (i != 0)
4731*f6dc9357SAndroid Build Coastguard Worker         printCallback->NewLine();
4732*f6dc9357SAndroid Build Coastguard Worker 
4733*f6dc9357SAndroid Build Coastguard Worker       const unsigned kNumCpuTests = 3;
4734*f6dc9357SAndroid Build Coastguard Worker       for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++)
4735*f6dc9357SAndroid Build Coastguard Worker       {
4736*f6dc9357SAndroid Build Coastguard Worker         PrintLeft(f, "CPU", kFieldSize_Name);
4737*f6dc9357SAndroid Build Coastguard Worker 
4738*f6dc9357SAndroid Build Coastguard Worker         // UInt32 resVal;
4739*f6dc9357SAndroid Build Coastguard Worker 
4740*f6dc9357SAndroid Build Coastguard Worker         CFreqBench fb;
4741*f6dc9357SAndroid Build Coastguard Worker         fb.complexInCommands = complexInCommands;
4742*f6dc9357SAndroid Build Coastguard Worker         fb.numThreads = numThreads;
4743*f6dc9357SAndroid Build Coastguard Worker         // showFreq;
4744*f6dc9357SAndroid Build Coastguard Worker         fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0);
4745*f6dc9357SAndroid Build Coastguard Worker         fb.specifiedFreq = specifiedFreq;
4746*f6dc9357SAndroid Build Coastguard Worker 
4747*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = fb.FreqBench(printCallback
4748*f6dc9357SAndroid Build Coastguard Worker             #ifndef Z7_ST
4749*f6dc9357SAndroid Build Coastguard Worker               , &affinityMode
4750*f6dc9357SAndroid Build Coastguard Worker             #endif
4751*f6dc9357SAndroid Build Coastguard Worker             );
4752*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
4753*f6dc9357SAndroid Build Coastguard Worker 
4754*f6dc9357SAndroid Build Coastguard Worker         cpuFreq = fb.CpuFreqRes;
4755*f6dc9357SAndroid Build Coastguard Worker         callback.NewLine();
4756*f6dc9357SAndroid Build Coastguard Worker 
4757*f6dc9357SAndroid Build Coastguard Worker         if (specifiedFreq != 0)
4758*f6dc9357SAndroid Build Coastguard Worker           cpuFreq = specifiedFreq;
4759*f6dc9357SAndroid Build Coastguard Worker 
4760*f6dc9357SAndroid Build Coastguard Worker         if (testTimeMs >= 1000)
4761*f6dc9357SAndroid Build Coastguard Worker         if (freqTest == kNumCpuTests - 1)
4762*f6dc9357SAndroid Build Coastguard Worker         {
4763*f6dc9357SAndroid Build Coastguard Worker           // SetComplexCommandsMs(testTimeMs, specifiedFreq != 0, cpuFreq, complexInCommands);
4764*f6dc9357SAndroid Build Coastguard Worker         }
4765*f6dc9357SAndroid Build Coastguard Worker       }
4766*f6dc9357SAndroid Build Coastguard Worker       callback.NewLine();
4767*f6dc9357SAndroid Build Coastguard Worker 
4768*f6dc9357SAndroid Build Coastguard Worker       // return S_OK; // change it
4769*f6dc9357SAndroid Build Coastguard Worker 
4770*f6dc9357SAndroid Build Coastguard Worker       callback.SetFreq(true, cpuFreq);
4771*f6dc9357SAndroid Build Coastguard Worker 
4772*f6dc9357SAndroid Build Coastguard Worker       if (!onlyHashBench)
4773*f6dc9357SAndroid Build Coastguard Worker       {
4774*f6dc9357SAndroid Build Coastguard Worker         size_t dataSize = (size_t)dict;
4775*f6dc9357SAndroid Build Coastguard Worker         if (use_fileData)
4776*f6dc9357SAndroid Build Coastguard Worker         {
4777*f6dc9357SAndroid Build Coastguard Worker           dataSize = fileDataBuffer.Size();
4778*f6dc9357SAndroid Build Coastguard Worker           if (dictIsDefined && dataSize > dict)
4779*f6dc9357SAndroid Build Coastguard Worker             dataSize = (size_t)dict;
4780*f6dc9357SAndroid Build Coastguard Worker         }
4781*f6dc9357SAndroid Build Coastguard Worker 
4782*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS
4783*f6dc9357SAndroid Build Coastguard Worker             method, complexInCommands,
4784*f6dc9357SAndroid Build Coastguard Worker           #ifndef Z7_ST
4785*f6dc9357SAndroid Build Coastguard Worker             numThreads,
4786*f6dc9357SAndroid Build Coastguard Worker             &affinityMode,
4787*f6dc9357SAndroid Build Coastguard Worker           #endif
4788*f6dc9357SAndroid Build Coastguard Worker             dictIsDefined || use_fileData, // forceUnpackSize
4789*f6dc9357SAndroid Build Coastguard Worker             dataSize,
4790*f6dc9357SAndroid Build Coastguard Worker             (const Byte *)fileDataBuffer,
4791*f6dc9357SAndroid Build Coastguard Worker             printCallback, &callback);
4792*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
4793*f6dc9357SAndroid Build Coastguard Worker       }
4794*f6dc9357SAndroid Build Coastguard Worker 
4795*f6dc9357SAndroid Build Coastguard Worker       {
4796*f6dc9357SAndroid Build Coastguard Worker         size_t dataSize = (size_t)1 << kNumHashDictBits;
4797*f6dc9357SAndroid Build Coastguard Worker         if (dictIsDefined)
4798*f6dc9357SAndroid Build Coastguard Worker         {
4799*f6dc9357SAndroid Build Coastguard Worker           dataSize = (size_t)dict;
4800*f6dc9357SAndroid Build Coastguard Worker           if (dataSize != dict)
4801*f6dc9357SAndroid Build Coastguard Worker             return E_OUTOFMEMORY;
4802*f6dc9357SAndroid Build Coastguard Worker         }
4803*f6dc9357SAndroid Build Coastguard Worker         if (use_fileData)
4804*f6dc9357SAndroid Build Coastguard Worker         {
4805*f6dc9357SAndroid Build Coastguard Worker           dataSize = fileDataBuffer.Size();
4806*f6dc9357SAndroid Build Coastguard Worker           if (dictIsDefined && dataSize > dict)
4807*f6dc9357SAndroid Build Coastguard Worker             dataSize = (size_t)dict;
4808*f6dc9357SAndroid Build Coastguard Worker         }
4809*f6dc9357SAndroid Build Coastguard Worker 
4810*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS
4811*f6dc9357SAndroid Build Coastguard Worker             method, complexInCommands,
4812*f6dc9357SAndroid Build Coastguard Worker             numThreads,
4813*f6dc9357SAndroid Build Coastguard Worker             dataSize, (const Byte *)fileDataBuffer,
4814*f6dc9357SAndroid Build Coastguard Worker             printCallback, &callback,
4815*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
4816*f6dc9357SAndroid Build Coastguard Worker           &affinityMode,
4817*f6dc9357SAndroid Build Coastguard Worker         #endif
4818*f6dc9357SAndroid Build Coastguard Worker           &callback.EncodeRes, true, cpuFreq);
4819*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
4820*f6dc9357SAndroid Build Coastguard Worker       }
4821*f6dc9357SAndroid Build Coastguard Worker 
4822*f6dc9357SAndroid Build Coastguard Worker       callback.NewLine();
4823*f6dc9357SAndroid Build Coastguard Worker       {
4824*f6dc9357SAndroid Build Coastguard Worker         PrintLeft(f, "CPU", kFieldSize_Name);
4825*f6dc9357SAndroid Build Coastguard Worker 
4826*f6dc9357SAndroid Build Coastguard Worker         CFreqBench fb;
4827*f6dc9357SAndroid Build Coastguard Worker         fb.complexInCommands = complexInCommands;
4828*f6dc9357SAndroid Build Coastguard Worker         fb.numThreads = numThreads;
4829*f6dc9357SAndroid Build Coastguard Worker         // showFreq;
4830*f6dc9357SAndroid Build Coastguard Worker         fb.showFreq = (specifiedFreq != 0);
4831*f6dc9357SAndroid Build Coastguard Worker         fb.specifiedFreq = specifiedFreq;
4832*f6dc9357SAndroid Build Coastguard Worker 
4833*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = fb.FreqBench(printCallback
4834*f6dc9357SAndroid Build Coastguard Worker           #ifndef Z7_ST
4835*f6dc9357SAndroid Build Coastguard Worker             , &affinityMode
4836*f6dc9357SAndroid Build Coastguard Worker           #endif
4837*f6dc9357SAndroid Build Coastguard Worker           );
4838*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
4839*f6dc9357SAndroid Build Coastguard Worker         callback.NewLine();
4840*f6dc9357SAndroid Build Coastguard Worker       }
4841*f6dc9357SAndroid Build Coastguard Worker     }
4842*f6dc9357SAndroid Build Coastguard Worker   }
4843*f6dc9357SAndroid Build Coastguard Worker   else
4844*f6dc9357SAndroid Build Coastguard Worker   {
4845*f6dc9357SAndroid Build Coastguard Worker     needSetComplexity = true;
4846*f6dc9357SAndroid Build Coastguard Worker     if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
4847*f6dc9357SAndroid Build Coastguard Worker     {
4848*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
4849*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++)
4850*f6dc9357SAndroid Build Coastguard Worker       {
4851*f6dc9357SAndroid Build Coastguard Worker         const CBenchMethod &h = g_Bench[i];
4852*f6dc9357SAndroid Build Coastguard Worker         AString benchMethod (h.Name);
4853*f6dc9357SAndroid Build Coastguard Worker         AString benchProps;
4854*f6dc9357SAndroid Build Coastguard Worker         const int propPos = benchMethod.Find(':');
4855*f6dc9357SAndroid Build Coastguard Worker         if (propPos >= 0)
4856*f6dc9357SAndroid Build Coastguard Worker         {
4857*f6dc9357SAndroid Build Coastguard Worker           benchProps = benchMethod.Ptr((unsigned)(propPos + 1));
4858*f6dc9357SAndroid Build Coastguard Worker           benchMethod.DeleteFrom((unsigned)propPos);
4859*f6dc9357SAndroid Build Coastguard Worker         }
4860*f6dc9357SAndroid Build Coastguard Worker 
4861*f6dc9357SAndroid Build Coastguard Worker         if (AreSameMethodNames(benchMethod, methodName))
4862*f6dc9357SAndroid Build Coastguard Worker         {
4863*f6dc9357SAndroid Build Coastguard Worker           if (benchProps.IsEmpty()
4864*f6dc9357SAndroid Build Coastguard Worker               || (benchProps == "x5" && method.PropsString.IsEmpty())
4865*f6dc9357SAndroid Build Coastguard Worker               || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps))
4866*f6dc9357SAndroid Build Coastguard Worker           {
4867*f6dc9357SAndroid Build Coastguard Worker             callback.BenchProps.EncComplex = h.EncComplex;
4868*f6dc9357SAndroid Build Coastguard Worker             callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
4869*f6dc9357SAndroid Build Coastguard Worker             callback.BenchProps.DecComplexUnc = h.DecComplexUnc;
4870*f6dc9357SAndroid Build Coastguard Worker             needSetComplexity = false;
4871*f6dc9357SAndroid Build Coastguard Worker             break;
4872*f6dc9357SAndroid Build Coastguard Worker           }
4873*f6dc9357SAndroid Build Coastguard Worker         }
4874*f6dc9357SAndroid Build Coastguard Worker       }
4875*f6dc9357SAndroid Build Coastguard Worker       /*
4876*f6dc9357SAndroid Build Coastguard Worker       if (i == Z7_ARRAY_SIZE(g_Bench))
4877*f6dc9357SAndroid Build Coastguard Worker         return E_NOTIMPL;
4878*f6dc9357SAndroid Build Coastguard Worker       */
4879*f6dc9357SAndroid Build Coastguard Worker     }
4880*f6dc9357SAndroid Build Coastguard Worker     if (needSetComplexity)
4881*f6dc9357SAndroid Build Coastguard Worker       callback.BenchProps.SetLzmaCompexity();
4882*f6dc9357SAndroid Build Coastguard Worker 
4883*f6dc9357SAndroid Build Coastguard Worker   if (startDicLog < kBenchMinDicLogSize)
4884*f6dc9357SAndroid Build Coastguard Worker     startDicLog = kBenchMinDicLogSize;
4885*f6dc9357SAndroid Build Coastguard Worker 
4886*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < numIterations; i++)
4887*f6dc9357SAndroid Build Coastguard Worker   {
4888*f6dc9357SAndroid Build Coastguard Worker     unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog;
4889*f6dc9357SAndroid Build Coastguard Worker     if (!multiDict)
4890*f6dc9357SAndroid Build Coastguard Worker       pow = 32;
4891*f6dc9357SAndroid Build Coastguard Worker     while (GetDictSizeFromLog(pow) > dict && pow > 0)
4892*f6dc9357SAndroid Build Coastguard Worker       pow--;
4893*f6dc9357SAndroid Build Coastguard Worker     for (; GetDictSizeFromLog(pow) <= dict; pow++)
4894*f6dc9357SAndroid Build Coastguard Worker     {
4895*f6dc9357SAndroid Build Coastguard Worker       Print_Pow(f, pow);
4896*f6dc9357SAndroid Build Coastguard Worker       callback.DictSize = (UInt64)1 << pow;
4897*f6dc9357SAndroid Build Coastguard Worker 
4898*f6dc9357SAndroid Build Coastguard Worker       COneMethodInfo method2 = method;
4899*f6dc9357SAndroid Build Coastguard Worker 
4900*f6dc9357SAndroid Build Coastguard Worker       if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
4901*f6dc9357SAndroid Build Coastguard Worker       {
4902*f6dc9357SAndroid Build Coastguard Worker         // We add dictionary size property.
4903*f6dc9357SAndroid Build Coastguard Worker         // method2 can have two different dictionary size properties.
4904*f6dc9357SAndroid Build Coastguard Worker         // And last property is main.
4905*f6dc9357SAndroid Build Coastguard Worker         NCOM::CPropVariant propVariant = (UInt32)pow;
4906*f6dc9357SAndroid Build Coastguard Worker         RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant))
4907*f6dc9357SAndroid Build Coastguard Worker       }
4908*f6dc9357SAndroid Build Coastguard Worker 
4909*f6dc9357SAndroid Build Coastguard Worker       size_t uncompressedDataSize;
4910*f6dc9357SAndroid Build Coastguard Worker       if (use_fileData)
4911*f6dc9357SAndroid Build Coastguard Worker       {
4912*f6dc9357SAndroid Build Coastguard Worker         uncompressedDataSize = fileDataBuffer.Size();
4913*f6dc9357SAndroid Build Coastguard Worker       }
4914*f6dc9357SAndroid Build Coastguard Worker       else
4915*f6dc9357SAndroid Build Coastguard Worker       {
4916*f6dc9357SAndroid Build Coastguard Worker         uncompressedDataSize = (size_t)callback.DictSize;
4917*f6dc9357SAndroid Build Coastguard Worker         if (uncompressedDataSize != callback.DictSize)
4918*f6dc9357SAndroid Build Coastguard Worker           return E_OUTOFMEMORY;
4919*f6dc9357SAndroid Build Coastguard Worker         if (uncompressedDataSize >= (1 << 18))
4920*f6dc9357SAndroid Build Coastguard Worker           uncompressedDataSize += kAdditionalSize;
4921*f6dc9357SAndroid Build Coastguard Worker       }
4922*f6dc9357SAndroid Build Coastguard Worker 
4923*f6dc9357SAndroid Build Coastguard Worker       const HRESULT res = MethodBench(
4924*f6dc9357SAndroid Build Coastguard Worker           EXTERNAL_CODECS_LOC_VARS
4925*f6dc9357SAndroid Build Coastguard Worker           complexInCommands,
4926*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
4927*f6dc9357SAndroid Build Coastguard Worker           true, numThreads,
4928*f6dc9357SAndroid Build Coastguard Worker           &affinityMode,
4929*f6dc9357SAndroid Build Coastguard Worker         #endif
4930*f6dc9357SAndroid Build Coastguard Worker           method2,
4931*f6dc9357SAndroid Build Coastguard Worker           uncompressedDataSize, (const Byte *)fileDataBuffer,
4932*f6dc9357SAndroid Build Coastguard Worker           kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
4933*f6dc9357SAndroid Build Coastguard Worker       f.NewLine();
4934*f6dc9357SAndroid Build Coastguard Worker       RINOK(res)
4935*f6dc9357SAndroid Build Coastguard Worker       if (!multiDict)
4936*f6dc9357SAndroid Build Coastguard Worker         break;
4937*f6dc9357SAndroid Build Coastguard Worker     }
4938*f6dc9357SAndroid Build Coastguard Worker   }
4939*f6dc9357SAndroid Build Coastguard Worker   }
4940*f6dc9357SAndroid Build Coastguard Worker 
4941*f6dc9357SAndroid Build Coastguard Worker   PrintChars(f, '-', callback.NameFieldSize + fileldSize);
4942*f6dc9357SAndroid Build Coastguard Worker 
4943*f6dc9357SAndroid Build Coastguard Worker   if (use2Columns)
4944*f6dc9357SAndroid Build Coastguard Worker   {
4945*f6dc9357SAndroid Build Coastguard Worker     f.Print(kSep);
4946*f6dc9357SAndroid Build Coastguard Worker     PrintChars(f, '-', fileldSize);
4947*f6dc9357SAndroid Build Coastguard Worker   }
4948*f6dc9357SAndroid Build Coastguard Worker 
4949*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4950*f6dc9357SAndroid Build Coastguard Worker 
4951*f6dc9357SAndroid Build Coastguard Worker   if (use2Columns)
4952*f6dc9357SAndroid Build Coastguard Worker   {
4953*f6dc9357SAndroid Build Coastguard Worker     PrintLeft(f, "Avr:", callback.NameFieldSize);
4954*f6dc9357SAndroid Build Coastguard Worker     PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes);
4955*f6dc9357SAndroid Build Coastguard Worker     f.Print(kSep);
4956*f6dc9357SAndroid Build Coastguard Worker     PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes);
4957*f6dc9357SAndroid Build Coastguard Worker     f.NewLine();
4958*f6dc9357SAndroid Build Coastguard Worker   }
4959*f6dc9357SAndroid Build Coastguard Worker 
4960*f6dc9357SAndroid Build Coastguard Worker   PrintLeft(f, "Tot:", callback.NameFieldSize);
4961*f6dc9357SAndroid Build Coastguard Worker   CTotalBenchRes midRes;
4962*f6dc9357SAndroid Build Coastguard Worker   midRes = callback.EncodeRes;
4963*f6dc9357SAndroid Build Coastguard Worker   midRes.Update_With_Res(callback.DecodeRes);
4964*f6dc9357SAndroid Build Coastguard Worker 
4965*f6dc9357SAndroid Build Coastguard Worker   // midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
4966*f6dc9357SAndroid Build Coastguard Worker   PrintTotals(f, showFreq, cpuFreq, false, midRes);
4967*f6dc9357SAndroid Build Coastguard Worker   f.NewLine();
4968*f6dc9357SAndroid Build Coastguard Worker 
4969*f6dc9357SAndroid Build Coastguard Worker   }
4970*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
4971*f6dc9357SAndroid Build Coastguard Worker }
4972