1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Bench.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#include <stdio.h>
6f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _WIN32
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define USE_POSIX_TIME
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define USE_POSIX_TIME2
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef USE_POSIX_TIME
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <time.h>
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef USE_POSIX_TIME2
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <sys/time.h>
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _WIN32
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define USE_ALLOCA
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef USE_ALLOCA
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _WIN32
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <malloc.h>
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <stdlib.h>
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zCrc.h"
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/Alloc.h"
33cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../../C/CpuArch.h"
34cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/System.h"
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _7ZIP_ST
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Windows/Synchronization.h"
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Windows/Thread.h"
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
42f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE)
43f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#define USE_WIN_FILE
44f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#endif
45f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
46f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#ifdef USE_WIN_FILE
47f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#include "../../../Windows/FileIO.h"
48f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#endif
49f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
50f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/IntToString.h"
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/StringConvert.h"
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/StringToInt.h"
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../Common/MethodProps.h"
56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../Common/StreamUtils.h"
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "Bench.h"
59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NWindows;
61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
62f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const UInt32 k_LZMA = 0x030101;
63f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt64 kComplexInCommands = (UInt64)1 <<
65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef UNDER_CE
66cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    31;
67cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #else
68cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    34;
69cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
71f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const UInt32 kComplexInSeconds = 4;
72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
73f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void SetComplexCommands(UInt32 complexInSeconds,
74f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands)
75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  complexInCommands = kComplexInCommands;
77f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const UInt64 kMinFreq = (UInt64)1000000 * 4;
78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const UInt64 kMaxFreq = (UInt64)1000000 * 20000;
79f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (cpuFreq < kMinFreq && !isSpecifiedFreq)
80f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    cpuFreq = kMinFreq;
81f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (cpuFreq < kMaxFreq || isSpecifiedFreq)
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
83cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (complexInSeconds != 0)
84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      complexInCommands = complexInSeconds * cpuFreq;
85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      complexInCommands = cpuFreq >> 2;
87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
88cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
89cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
90cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const unsigned kNumHashDictBits = 17;
91cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 kFilterUnpackSize = (48 << 10);
92cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
93cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const unsigned kOldLzmaDictBits = 30;
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
95baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kAdditionalSize = (1 << 16);
96baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kCompressedAdditionalSize = (1 << 10);
97baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kMaxLzmaPropSize = 5;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
99baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBaseRandomGenerator
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 A1;
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 A2;
103baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBaseRandomGenerator() { Init(); }
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init() { A1 = 362436069; A2 = 521288629;}
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 GetRnd()
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
114f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
115f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kBufferAlignment = 1 << 4;
116f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
117f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastruct CBenchBuffer
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t BufferSize;
120f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
121f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #ifdef _WIN32
122f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *Buffer;
124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
125f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CBenchBuffer(): BufferSize(0), Buffer(NULL) {}
126f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  ~CBenchBuffer() { ::MidFree(Buffer); }
127f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
128f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  void AllocAlignedMask(size_t size, size_t)
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::MidFree(Buffer);
131f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    BufferSize = 0;
132f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Buffer = (Byte *)::MidAlloc(size);
133f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (Buffer)
134f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      BufferSize = size;
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
136f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
137f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #else
138f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
139f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  Byte *Buffer;
140f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  Byte *_bufBase;
141f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
142f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){}
143f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  ~CBenchBuffer() { ::MidFree(_bufBase); }
144f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
145f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  void AllocAlignedMask(size_t size, size_t alignMask)
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
147f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ::MidFree(_bufBase);
148f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Buffer = NULL;
149f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    BufferSize = 0;
150f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    _bufBase = (Byte *)::MidAlloc(size + alignMask);
151f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
152f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (_bufBase)
153f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
154f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      // Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
155f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka         Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
156f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      BufferSize = size;
157f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
158f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
159f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
160f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #endif
161f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
162f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool Alloc(size_t size)
163f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
164f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (Buffer && BufferSize == size)
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true;
166f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    AllocAlignedMask(size, kBufferAlignment - 1);
167f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    return (Buffer != NULL || size == 0);
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
171f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
172baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBenchRandomGenerator: public CBenchBuffer
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
174f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  static UInt32 GetVal(UInt32 &res, unsigned numBits)
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 val = res & (((UInt32)1 << numBits) - 1);
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res >>= numBits;
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return val;
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
181f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  static UInt32 GetLen(UInt32 &r)
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
183f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32 len = GetVal(r, 2);
184f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    return GetVal(r, 1 + len);
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
187f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakapublic:
188f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
189f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  void GenerateSimpleRandom(CBaseRandomGenerator *_RG_)
190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CBaseRandomGenerator rg = *_RG_;
192f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const size_t bufSize = BufferSize;
193f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Byte *buf = Buffer;
194f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    for (size_t i = 0; i < bufSize; i++)
195f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      buf[i] = (Byte)rg.GetRnd();
196f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    *_RG_ = rg;
197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
199f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_)
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
201f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CBaseRandomGenerator rg = *_RG_;
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 pos = 0;
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 rep0 = 1;
204f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const size_t bufSize = BufferSize;
205f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Byte *buf = Buffer;
206f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    unsigned posBits = 1;
207f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
208f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    while (pos < bufSize)
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
210f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt32 r = rg.GetRnd();
211f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (GetVal(r, 1) == 0 || pos < 1024)
212f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        buf[pos++] = (Byte)(r & 0xFF);
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt32 len;
216f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        len = 1 + GetLen(r);
217f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
218f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (GetVal(r, 3) != 0)
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
220f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          len += GetLen(r);
221f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
222f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          while (((UInt32)1 << posBits) < pos)
223f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            posBits++;
224f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
225f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          unsigned numBitsMax = dictBits;
226f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (numBitsMax > posBits)
227f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            numBitsMax = posBits;
228f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
229f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          const unsigned kAddBits = 6;
230f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          unsigned numLogBits = 5;
231f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (numBitsMax <= (1 << 4) - 1 + kAddBits)
232f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            numLogBits = 4;
233f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
234f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          for (;;)
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
236f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            UInt32 ppp = GetVal(r, numLogBits) + kAddBits;
237f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            r = rg.GetRnd();
238f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            if (ppp > numBitsMax)
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              continue;
240f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            rep0 = GetVal(r, ppp);
241f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            if (rep0 < pos)
242f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka              break;
243f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            r = rg.GetRnd();
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          rep0++;
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
248f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        {
249f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          UInt32 rem = (UInt32)bufSize - pos;
250f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (len > rem)
251f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            len = rem;
252f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        }
253f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        Byte *dest = buf + pos;
254f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        const Byte *src = dest - rep0;
255f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        pos += len;
256f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        for (UInt32 i = 0; i < len; i++)
257f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          *dest++ = *src++;
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
260f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
261f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    *_RG_ = rg;
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
266baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBenchmarkInStream:
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ISequentialInStream,
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const Byte *Data;
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t Pos;
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t Size;
273baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init(const Byte *data, size_t size)
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Data = data;
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Size = size;
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Pos = 0;
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
284baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t remain = Size - Pos;
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 kMaxBlockSize = (1 << 20);
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (size > kMaxBlockSize)
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size = kMaxBlockSize;
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (size > remain)
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size = (UInt32)remain;
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (UInt32 i = 0; i < size; i++)
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ((Byte *)data)[i] = Data[Pos + i];
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Pos += size;
295f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (processedSize)
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *processedSize = size;
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
300baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBenchmarkOutStream:
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ISequentialOutStream,
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CBenchBuffer,
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // bool _overflow;
306baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
307f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t Pos;
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool RealCopy;
309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool CalcCrc;
310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 Crc;
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // CBenchmarkOutStream(): _overflow(false) {}
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Init(bool realCopy, bool calcCrc)
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Crc = CRC_INIT_VAL;
316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RealCopy = realCopy;
317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CalcCrc = calcCrc;
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // _overflow = false;
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Pos = 0;
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
321f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
322f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); }
323f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
328baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t curSize = BufferSize - Pos;
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (curSize > size)
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    curSize = size;
333f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (curSize != 0)
334f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
335f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (RealCopy)
336f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      memcpy(Buffer + Pos, data, curSize);
337f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (CalcCrc)
338f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      Crc = CrcUpdate(Crc, data, curSize);
339f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Pos += curSize;
340f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
341f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (processedSize)
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *processedSize = (UInt32)curSize;
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (curSize != size)
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // _overflow = true;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
351baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CCrcOutStream:
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public ISequentialOutStream,
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
355baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool CalcCrc;
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 Crc;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP
359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
360cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCrcOutStream(): CalcCrc(true) {};
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init() { Crc = CRC_INIT_VAL; }
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
365baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
367cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (CalcCrc)
368cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Crc = CrcUpdate(Crc, data, size);
369f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (processedSize)
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *processedSize = size;
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
374baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt64 GetTimeCount()
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_POSIX_TIME
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_POSIX_TIME2
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  timeval v;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (gettimeofday(&v, 0) == 0)
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (UInt64)time(NULL) * 1000000;
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return time(NULL);
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /*
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LARGE_INTEGER value;
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::QueryPerformanceCounter(&value))
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return value.QuadPart;
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  */
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return GetTickCount();
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
395baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt64 GetFreq()
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_POSIX_TIME
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_POSIX_TIME2
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 1000000;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 1;
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /*
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LARGE_INTEGER value;
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::QueryPerformanceFrequency(&value))
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return value.QuadPart;
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  */
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 1000;
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef USE_POSIX_TIME
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CUserTime
416cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 Sum;
418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  clock_t Prev;
419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
420cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Init()
421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Prev = clock();
423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Sum = 0;
424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GetUserTime()
427cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    clock_t v = clock();
429cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Sum += v - Prev;
430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Prev = v;
431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return Sum;
432cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#else
436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 GetWinUserTime()
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  FILETIME creationTime, exitTime, kernelTime, userTime;
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef UNDER_CE
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::GetThreadTimes(::GetCurrentThread()
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::GetProcessTimes(::GetCurrentProcess()
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    , &creationTime, &exitTime, &kernelTime, &userTime) != 0)
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return GetTime64(userTime) + GetTime64(kernelTime);
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (UInt64)GetTickCount() * 10000;
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CUserTime
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 StartTime;
455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Init() { StartTime = GetWinUserTime(); }
457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GetUserTime() { return GetWinUserTime() - StartTime; }
458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
462baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt64 GetUserFreq()
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_POSIX_TIME
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return CLOCKS_PER_SEC;
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 10000000;
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
471baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBenchProgressStatus
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NSynchronization::CCriticalSection CS;
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
476baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Res;
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool EncodeMode;
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void SetResult(HRESULT res)
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NSynchronization::CCriticalSectionLock lock(CS);
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Res = res;
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT GetResult()
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NSynchronization::CCriticalSectionLock lock(CS);
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return Res;
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CBenchInfoCalc
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchInfo BenchInfo;
498cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CUserTime UserTime;
499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void SetStartTime();
501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void SetFinishTime(CBenchInfo &dest);
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CBenchInfoCalc::SetStartTime()
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  BenchInfo.GlobalFreq = GetFreq();
507cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  BenchInfo.UserFreq = GetUserFreq();
508cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  BenchInfo.GlobalTime = ::GetTimeCount();
509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  BenchInfo.UserTime = 0;
510cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UserTime.Init();
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CBenchInfoCalc::SetFinishTime(CBenchInfo &dest)
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest = BenchInfo;
516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime;
517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest.UserTime = UserTime.GetUserTime();
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyclass CBenchProgressInfo:
521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  public ICompressProgressInfo,
522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  public CMyUnknownImp,
523cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  public CBenchInfoCalc
524cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckypublic:
526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProgressStatus *Status;
527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT Res;
528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IBenchCallback *Callback;
529cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProgressInfo(): Callback(0) {}
531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  MY_UNKNOWN_IMP
532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
535baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT res = Status->GetResult();
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res != S_OK)
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return res;
540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!Callback)
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return res;
542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfo info;
543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  SetFinishTime(info);
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (Status->EncodeMode)
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
546cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    info.UnpackSize = BenchInfo.UnpackSize + *inSize;
547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    info.PackSize = BenchInfo.PackSize + *outSize;
548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    res = Callback->SetEncodeResult(info, false);
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.PackSize = BenchInfo.PackSize + *inSize;
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.UnpackSize = BenchInfo.UnpackSize + *outSize;
554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    res = Callback->SetDecodeResult(info, false);
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res != S_OK)
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Status->SetResult(res);
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
561f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kSubBits = 8;
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
563baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt32 GetLogSize(UInt32 size)
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
565f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  for (unsigned i = kSubBits; i < 32; i++)
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UInt32 j = 0; j < (1 << kSubBits); j++)
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return (i << kSubBits) + j;
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (32 << kSubBits);
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
572baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void NormalizeVals(UInt64 &v1, UInt64 &v2)
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (v1 > 1000000)
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v1 >>= 1;
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v2 >>= 1;
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
581cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CBenchInfo::GetUsage() const
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
583cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 userTime = UserTime;
584cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 userFreq = UserFreq;
585cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 globalTime = GlobalTime;
586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 globalFreq = GlobalFreq;
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(userTime, userFreq);
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(globalFreq, globalTime);
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (userFreq == 0)
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    userFreq = 1;
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (globalTime == 0)
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    globalTime = 1;
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return userTime * globalFreq * 1000000 / userFreq / globalTime;
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
596cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 userTime = UserTime;
599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 userFreq = UserFreq;
600cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 globalTime = GlobalTime;
601cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 globalFreq = GlobalFreq;
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(userFreq, userTime);
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(globalTime, globalFreq);
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (globalFreq == 0)
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    globalFreq = 1;
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (userTime == 0)
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    userTime = 1;
608cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return userFreq * globalTime / globalFreq * rating / userTime;
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
611baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 elTime = elapsedTime;
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NormalizeVals(freq, elTime);
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (elTime == 0)
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    elTime = 1;
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return value * freq / elTime;
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
620cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const
621cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
622cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return MyMultDiv64(numCommands, GlobalTime, GlobalFreq);
623cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
624cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CBenchProps
626cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
627cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool LzmaRatingMode;
628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
629cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 EncComplex;
630cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 DecComplexCompr;
631cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 DecComplexUnc;
632cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProps(): LzmaRatingMode(false) {}
634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void SetLzmaCompexity();
635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GeComprCommands(UInt64 unpackSize)
637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return unpackSize * EncComplex;
639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
640cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
641cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize)
642cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
643cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return (packSize * DecComplexCompr + unpackSize * DecComplexUnc);
644cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
645cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
646cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
647cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
648cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
649cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
650cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CBenchProps::SetLzmaCompexity()
651cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
652cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  EncComplex = 1200;
653cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  DecComplexUnc = 4;
654cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  DecComplexCompr = 190;
655cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  LzmaRatingMode = true;
656cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
657cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
658cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (dictSize < (1 << kBenchMinDicLogSize))
661cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    dictSize = (1 << kBenchMinDicLogSize);
662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 encComplex = EncComplex;
663cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (LzmaRatingMode)
664cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
665cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits);
666cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
667cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
668cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 numCommands = (UInt64)size * encComplex;
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyMultDiv64(numCommands, elapsedTime, freq);
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
672cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
674cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations;
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyMultDiv64(numCommands, elapsedTime, freq);
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
679cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
680cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProps props;
681cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  props.SetLzmaCompexity();
682cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return props.GetCompressRating(dictSize, elapsedTime, freq, size);
683cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
684cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
685cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations)
686cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
687cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProps props;
688cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  props.SetLzmaCompexity();
689cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations);
690cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
691cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
692baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CEncoderInfo;
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
694baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CEncoderInfo
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::CThread thread[2];
698cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 NumDecoderSubThreads;
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
700cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressCoder> _encoder;
701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressFilter> _encoderFilter;
702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchProgressInfo *progressInfoSpec[2];
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ICompressProgressInfo> progressInfo[2];
704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 NumIterations;
705f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef USE_ALLOCA
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t AllocaSize;
708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Byte _key[32];
711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Byte _iv[16];
712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Byte _psw[16];
713cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool CheckCrc_Enc;
714cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool CheckCrc_Dec;
715cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  struct CDecoderInfo
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo *Encoder;
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 DecoderIndex;
720f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool CallbackMode;
721f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef USE_ALLOCA
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t AllocaSize;
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  };
726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CDecoderInfo decodersInfo[2];
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
728cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressCoder> _decoders[2];
729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressFilter> _decoderFilter;
730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Results[2];
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchmarkOutStream *outStreamSpec;
733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> outStream;
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IBenchCallback *callback;
735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IBenchPrintCallback *printCallback;
736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 crc;
737f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t kBufferSize;
738f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t compressedSize;
739f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const Byte *uncompressedDataPtr;
740f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
741f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const Byte *fileData;
742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchRandomGenerator rg;
743f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
744cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchBuffer rgCopy; // it must be 16-byte aligned !!!
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchmarkOutStream *propStreamSpec;
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> propStream;
747cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
748cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // for decode
749cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  COneMethodInfo _method;
750f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t _uncompressedDataSize;
751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
752cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT Init(
753cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const COneMethodInfo &method,
754cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned generateDictBits,
755cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBaseRandomGenerator *rg);
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Encode();
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Decode(UInt32 decoderIndex);
758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
759cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CEncoderInfo():
760f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    fileData(NULL),
761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CheckCrc_Enc(true),
762cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CheckCrc_Dec(true),
763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
766f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res;
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo *encoder = (CEncoderInfo *)param;
771cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    try
772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #ifdef USE_ALLOCA
774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      alloca(encoder->AllocaSize);
775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #endif
776f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
777cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      res = encoder->Encode();
778cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder->Results[0] = res;
779cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
780cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    catch(...)
781cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
782cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      res = E_FAIL;
783cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res != S_OK)
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encoder->progressInfoSpec[0]->Status->SetResult(res);
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
788f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CDecoderInfo *decoder = (CDecoderInfo *)param;
792f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef USE_ALLOCA
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    alloca(decoder->AllocaSize);
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
796f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo *encoder = decoder->Encoder;
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT CreateEncoderThread()
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return thread[0].Create(EncodeThreadFunction, this);
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
807f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  HRESULT CreateDecoderThread(unsigned index, bool callbackMode
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifdef USE_ALLOCA
809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      , size_t allocaSize
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      )
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CDecoderInfo &decoder = decodersInfo[index];
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    decoder.DecoderIndex = index;
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    decoder.Encoder = this;
816f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef USE_ALLOCA
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    decoder.AllocaSize = allocaSize;
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
820f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    decoder.CallbackMode = callbackMode;
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return thread[index].Create(DecodeThreadFunction, &decoder);
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
824f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
828cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
829cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CEncoderInfo::Init(
830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const COneMethodInfo &method,
831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned generateDictBits,
832cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CBaseRandomGenerator *rgLoc)
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
834f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  // we need extra space, if input data is already compressed
835f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const size_t kCompressedBufferSize =
836f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      kCompressedAdditionalSize +
837f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      kBufferSize + kBufferSize / 16;
838f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      // kBufferSize / 2;
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
840f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (kCompressedBufferSize < kBufferSize)
841f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    return E_FAIL;
842f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
843f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  uncompressedDataPtr = fileData;
844f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
845f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (!fileData)
846f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
847f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (!rg.Alloc(kBufferSize))
848f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      return E_OUTOFMEMORY;
849f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
850f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // DWORD ttt = GetTickCount();
851f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (generateDictBits == 0)
852f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      rg.GenerateSimpleRandom(rgLoc);
853f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    else
854f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      rg.GenerateLz(generateDictBits, rgLoc);
855f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // printf("\n%d\n            ", GetTickCount() - ttt);
856f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
857f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    crc = CrcCalc(rg.Buffer, rg.BufferSize);
858f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    uncompressedDataPtr = rg.Buffer;
859f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
860f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
861cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_encoderFilter)
862cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
863f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (!rgCopy.Alloc(kBufferSize))
864cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_OUTOFMEMORY;
865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
866cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
867cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  outStreamSpec = new CBenchmarkOutStream;
869f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  outStream = outStreamSpec;
870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!outStreamSpec->Alloc(kCompressedBufferSize))
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_OUTOFMEMORY;
872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  propStreamSpec = 0;
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!propStream)
875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    propStreamSpec = new CBenchmarkOutStream;
877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    propStream = propStreamSpec;
878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_OUTOFMEMORY;
881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  propStreamSpec->Init(true, false);
882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IUnknown> coder;
885cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_encoderFilter)
886cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = _encoderFilter;
887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = _encoder;
889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
890cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<ICompressSetCoderProperties> scp;
891cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
892cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (scp)
893cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
894f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt64 reduceSize = kBufferSize;
895cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(method.SetCoderProps(scp, &reduceSize));
896cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
897cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
898cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
899cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (method.AreThereNonOptionalProps())
900cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<ICompressWriteCoderProperties> writeCoderProps;
904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (writeCoderProps)
906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
907cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(writeCoderProps->WriteCoderProperties(propStream));
908cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CMyComPtr<ICryptoSetPassword> sp;
912cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      coder.QueryInterface(IID_ICryptoSetPassword, &sp);
913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (sp)
914cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
915cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
916cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
917cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // we must call encoding one time to calculate password key for key cache.
918cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // it must be after WriteCoderProperties!
919cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        Byte temp[16];
920cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        memset(temp, 0, sizeof(temp));
921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
922cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (_encoderFilter)
923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
924cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          _encoderFilter->Init();
925cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          _encoderFilter->Filter(temp, sizeof(temp));
926cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
927cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else
928cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
929f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
930f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
931f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          inStreamSpec->Init(temp, sizeof(temp));
932f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
933f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          CCrcOutStream *crcStreamSpec = new CCrcOutStream;
934f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          CMyComPtr<ISequentialOutStream> crcStream = crcStreamSpec;
935f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          crcStreamSpec->Init();
936f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
937f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          RINOK(_encoder->Code(inStream, crcStream, 0, 0, NULL));
938cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
939cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
940baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
942f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
943baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
945baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
946f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
947f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size)
948f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{
949f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  while (size != 0)
950f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
951f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32 cur = (UInt32)1 << 31;
952f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (cur > size)
953f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      cur = (UInt32)size;
954f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32 processed = filter->Filter(data, cur);
955f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    data += processed;
956f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // if (processed > size) (in AES filter), we must fill last block with zeros.
957f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // but it is not important for benchmark. So we just copy that data without filtering.
958f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (processed > size || processed == 0)
959f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      break;
960f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    size -= processed;
961f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
962f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka}
963f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
964f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
965baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoderInfo::Encode()
966baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
967cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
968cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bi.UnpackSize = 0;
969cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bi.PackSize = 0;
970cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICryptoProperties> cp;
971cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IUnknown> coder;
972cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_encoderFilter)
973cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = _encoderFilter;
974cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
975cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = _encoder;
976cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  coder.QueryInterface(IID_ICryptoProperties, &cp);
977baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
978baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 prev = 0;
980baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 crcPrev = 0;
982cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (cp)
984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
985cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(cp->SetKey(_key, sizeof(_key)));
986cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
987cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
988cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
989cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt64 i = 0; i < NumIterations; i++)
990cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
991cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (printCallback && bi.UnpackSize - prev > (1 << 20))
992cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
993cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(printCallback->CheckBreak());
994cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      prev = bi.UnpackSize;
995cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
996cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
997cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool isLast = (i == NumIterations - 1);
998cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool calcCrc = ((isLast || (i & 0x7F) == 0 || CheckCrc_Enc) && NumIterations != 1);
999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStreamSpec->Init(isLast, calcCrc);
1000cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1001cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_encoderFilter)
1002cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1003f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize);
1004cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _encoderFilter->Init();
1005f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize);
1006f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize));
1007cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1008cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1009cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1010f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      inStreamSpec->Init(uncompressedDataPtr, kBufferSize);
1011f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0]));
1012cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1013cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1014f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // outStreamSpec->Print();
1015f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1016cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 crcNew = CRC_GET_DIGEST(outStreamSpec->Crc);
1017cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (i == 0)
1018cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      crcPrev = crcNew;
1019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else if (calcCrc && crcPrev != crcNew)
1020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_FAIL;
1021f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    compressedSize = outStreamSpec->Pos;
1023f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bi.UnpackSize += kBufferSize;
1024cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bi.PackSize += compressedSize;
1025cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1026f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1027cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _encoder.Release();
1028cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _encoderFilter.Release();
1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1032f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1033baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
1034baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1035baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
1037cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressCoder> &decoder = _decoders[decoderIndex];
1038cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IUnknown> coder;
1039cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_decoderFilter)
1040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1041cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (decoderIndex != 0)
1042cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_FAIL;
1043cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = _decoderFilter;
1044cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1045cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
1046cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder = decoder;
1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1048cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
1049cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
1050cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!setDecProps && propStreamSpec->Pos != 0)
1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
1055baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pi->BenchInfo.UnpackSize = 0;
1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pi->BenchInfo.PackSize = 0;
1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1060cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifndef _7ZIP_ST
1061cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1062cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<ICompressSetCoderMt> setCoderMt;
1063cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
1064cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (setCoderMt)
1065cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1066cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads));
1067cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1068cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1069cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
1070cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1071cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICompressSetCoderProperties> scp;
1072cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  coder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
1073cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (scp)
1074cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1075cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 reduceSize = _uncompressedDataSize;
1076cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(_method.SetCoderProps(scp, &reduceSize));
1077cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1078cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1079cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ICryptoProperties> cp;
1080cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  coder.QueryInterface(IID_ICryptoProperties, &cp);
1081cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1082cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (setDecProps)
1083cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1084f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos));
1085cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1086cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1087cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1088cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<ICryptoSetPassword> sp;
1089cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    coder.QueryInterface(IID_ICryptoSetPassword, &sp);
1090cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (sp)
1091cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1092cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw)));
1093cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1094cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1095cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1096cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 prev = 0;
1097cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1098cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (cp)
1099cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(cp->SetKey(_key, sizeof(_key)));
1101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
1102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1103cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1104cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt64 i = 0; i < NumIterations; i++)
1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (printCallback && pi->BenchInfo.UnpackSize - prev > (1 << 20))
1107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(printCallback->CheckBreak());
1109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      prev = pi->BenchInfo.UnpackSize;
1110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    crcOutStreamSpec->Init();
1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 outSize = kBufferSize;
1116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    crcOutStreamSpec->CalcCrc = ((i & 0x7F) == 0 || CheckCrc_Dec);
1117f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_decoderFilter)
1119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (compressedSize > rgCopy.BufferSize)
1121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_FAIL;
1122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize);
1123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _decoderFilter->Init();
1124f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize);
1125f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize));
1126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
1130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1131f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (crcOutStreamSpec->CalcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
1133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_FALSE;
1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pi->BenchInfo.UnpackSize += kBufferSize;
1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pi->BenchInfo.PackSize += compressedSize;
1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1137f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  decoder.Release();
1139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _decoderFilter.Release();
1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1143f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 kNumThreadsMax = (1 << 12);
1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1146baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CBenchEncoders
1147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CEncoderInfo *encoders;
1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CBenchEncoders() { delete []encoders; }
1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1153f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numCommands < (1 << 4))
1157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numCommands = (1 << 4);
1158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 res = complexInCommands / numCommands;
1159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (res == 0 ? 1 : res);
1160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1162f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT MethodBench(
1164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    DECL_EXTERNAL_CODECS_LOC_VARS
1165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 complexInCommands,
1166f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool
1167f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #ifndef _7ZIP_ST
1168f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        oldLzmaBenchMode
1169f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #endif
1170f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ,
1171f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32
1172f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #ifndef _7ZIP_ST
1173f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        numThreads
1174f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #endif
1175f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ,
1176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const COneMethodInfo &method2,
1177f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    size_t uncompressedDataSize,
1178f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const Byte *fileData,
1179cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned generateDictBits,
1180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *printCallback,
1182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchCallback *callback,
1183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CBenchProps *benchProps)
1184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  COneMethodInfo method = method2;
1186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 methodId;
1187f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numStreams;
1188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!FindMethod(
1189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      EXTERNAL_CODECS_LOC_VARS
1190f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      method.MethodName, methodId, numStreams))
1191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_NOTIMPL;
1192f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numStreams != 1)
1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
1194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1195cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 numEncoderThreads = 1;
1196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 numSubDecoderThreads = 1;
1197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifndef _7ZIP_ST
1199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numEncoderThreads = numThreads;
1200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (oldLzmaBenchMode && methodId == k_LZMA)
1202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bool fixedNumber;
1204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
1205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!fixedNumber && numThreads == 1)
1206f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        method.AddProp_NumThreads(1);
1207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (numThreads > 1 && numLzmaThreads > 1)
1208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numEncoderThreads = numThreads / 2;
1210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numSubDecoderThreads = 2;
1211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
1214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchEncoders encodersSpec(numEncoderThreads);
1216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CEncoderInfo *encoders = encodersSpec.encoders;
1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
1219f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo &encoder = encoders[i];
1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoder.callback = (i == 0) ? callback : 0;
1224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder.printCallback = printCallback;
1225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1226f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
1227f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      CCreatedCoder cod;
1228f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod));
1229f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      encoder._encoder = cod.Coder;
1230f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (!encoder._encoder && !encoder._encoderFilter)
1231f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_NOTIMPL;
1232f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
1233cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1234cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30 ;
1235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30 ;
1236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    memset(encoder._iv, 0, sizeof(encoder._iv));
1238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    memset(encoder._key, 0, sizeof(encoder._key));
1239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    memset(encoder._psw, 0, sizeof(encoder._psw));
1240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1243f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      CCreatedCoder cod;
1244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
1245f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
1246f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      decoder = cod.Coder;
1247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!encoder._decoderFilter && !decoder)
1248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_NOTIMPL;
1249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBaseRandomGenerator rg;
1253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  rg.Init();
1254f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1255f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 crc = 0;
1256f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (fileData)
1257f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    crc = CrcCalc(fileData, uncompressedDataSize);
1258f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CEncoderInfo &encoder = encoders[i];
1262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder._method = method;
1263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder._uncompressedDataSize = uncompressedDataSize;
1264f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    encoder.kBufferSize = uncompressedDataSize;
1265f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    encoder.fileData = fileData;
1266f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    encoder.crc = crc;
1267f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1268f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    RINOK(encoders[i].Init(method, generateDictBits, &rg));
1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchProgressStatus status;
1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  status.Res = S_OK;
1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  status.EncodeMode = true;
1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo &encoder = encoders[i];
1278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands);
1279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int j = 0; j < 2; j++)
1281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBenchProgressInfo *spec = new CBenchProgressInfo;
1283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder.progressInfoSpec[j] = spec;
1284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder.progressInfo[j] = spec;
1285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      spec->Status = &status;
1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1287f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (i == 0)
1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
1291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->Callback = callback;
1292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->BenchInfo.NumIterations = numEncoderThreads;
1293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->SetStartTime();
1294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
1297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numEncoderThreads > 1)
1298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifdef USE_ALLOCA
1300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
1301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
1302f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(encoder.CreateEncoderThread())
1304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
1306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
1307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(encoder.Encode());
1309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1311f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
1313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numEncoderThreads > 1)
1314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numEncoderThreads; i++)
1315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encoders[i].thread[0].Wait();
1316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(status.Res);
1319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchInfo info;
1321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  encoders[0].progressInfoSpec[0]->SetFinishTime(info);
1323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  info.UnpackSize = 0;
1324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  info.PackSize = 0;
1325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.NumIterations = encoders[0].NumIterations;
1326f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo &encoder = encoders[i];
1330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.UnpackSize += encoder.kBufferSize;
1331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.PackSize += encoder.compressedSize;
1332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1333f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(callback->SetEncodeResult(info, true));
1335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  status.Res = S_OK;
1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  status.EncodeMode = false;
1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
1341f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo &encoder = encoders[i];
1345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (i == 0)
1347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands);
1349cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
1350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->Callback = callback;
1351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->BenchInfo.NumIterations = numDecoderThreads;
1352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bpi->SetStartTime();
1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder.NumIterations = encoders[0].NumIterations;
1356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
1358cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      int numSubThreads = method.Get_NumThreads();
1360cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : numSubThreads;
1361cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numDecoderThreads > 1)
1363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            #ifdef USE_ALLOCA
1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF
1369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            #endif
1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            );
1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(res);
1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
1375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(encoder.Decode(0));
1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1380f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
1382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT res = S_OK;
1383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDecoderThreads > 1)
1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numEncoderThreads; i++)
1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CEncoderInfo &encoder = encoders[i];
1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        encoder.thread[j].Wait();
1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (encoder.Results[j] != S_OK)
1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = encoder.Results[j];
1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(res);
1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1394f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(status.Res);
1396cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  encoders[0].progressInfoSpec[0]->SetFinishTime(info);
1397f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
1399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef UNDER_CE
1400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDecoderThreads > 1)
1401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numEncoderThreads; i++)
1402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
1403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        FILETIME creationTime, exitTime, kernelTime, userTime;
1405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0)
1406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          info.UserTime += GetTime64(userTime) + GetTime64(kernelTime);
1407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  info.UnpackSize = 0;
1412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  info.PackSize = 0;
1413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
1414f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEncoderThreads; i++)
1416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoderInfo &encoder = encoders[i];
1418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.UnpackSize += encoder.kBufferSize;
1419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    info.PackSize += encoder.compressedSize;
1420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1421f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(callback->SetDecodeResult(info, false));
1423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(callback->SetDecodeResult(info, true));
1424f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
1426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1429f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
1430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 hs = dictionary - 1;
1432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs |= (hs >> 1);
1433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs |= (hs >> 2);
1434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs |= (hs >> 4);
1435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs |= (hs >> 8);
1436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs >>= 1;
1437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs |= 0xFFFF;
1438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (hs > (1 << 24))
1439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    hs >>= 1;
1440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  hs++;
1441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 +
1442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      (1 << 20) + (multiThread ? (6 << 20) : 0);
1443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1445f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaUInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench)
1446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kBufferSize = dictionary;
1448f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const UInt32 kCompressedBufferSize = kBufferSize; // / 2;
1449f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool lzmaMt = (totalBench || numThreads > 1);
1450f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numBigThreads = numThreads;
1451f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (!totalBench && lzmaMt)
1452f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    numBigThreads /= 2;
1453f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  return ((UInt64)kBufferSize + kCompressedBufferSize +
1454f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads;
1455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT CrcBig(const void *data, UInt32 size, UInt64 numIterations,
1458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UInt32 *checkSum, IHasher *hf,
1459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *callback)
1460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Byte hash[64];
1462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 i;
1463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < sizeof(hash); i++)
1464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hash[i] = 0;
1465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < numIterations; i++)
1466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (callback && (i & 0xFF) == 0)
1468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(callback->CheckBreak());
1470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hf->Init();
1472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hf->Update(data, size);
1473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hf->Final(hash);
1474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 hashSize = hf->GetDigestSize();
1475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (hashSize > sizeof(hash))
1476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_FALSE;
1477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 sum = 0;
1478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt32 j = 0; j < hashSize; j += 4)
1479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      sum ^= GetUi32(hash + j);
1480cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (checkSum && sum != *checkSum)
1481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_FALSE;
1483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
1486cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt32 g_BenchCpuFreqTemp = 1;
1489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define YY1 sum += val; sum ^= val;
1491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define YY3 YY1 YY1 YY1 YY1
1492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define YY5 YY3 YY3 YY3 YY3
1493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define YY7 YY5 YY5 YY5 YY5
1494cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 kNumFreqCommands = 128;
1495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1496f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaEXTERN_C_BEGIN
1497f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1498cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val)
1499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt32 i = 0; i < num; i++)
1501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    YY7
1503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return sum;
1505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1507f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaEXTERN_C_END
1508f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1509f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _7ZIP_ST
1511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CFreqInfo
1513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NWindows::CThread Thread;
1515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IBenchPrintCallback *Callback;
1516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT CallbackRes;
1517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 ValRes;
1518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 Size;
1519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 NumIterations;
1520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Wait()
1522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Thread.Wait();
1524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Thread.Close();
1525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
1527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic THREAD_FUNC_DECL FreqThreadFunction(void *param)
1529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CFreqInfo *p = (CFreqInfo *)param;
1531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 sum = g_BenchCpuFreqTemp;
1533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt64 k = p->NumIterations; k > 0; k--)
1534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p->CallbackRes = p->Callback->CheckBreak();
1536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (p->CallbackRes != S_OK)
1537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 0;
1538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp);
1539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p->ValRes = sum;
1541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 0;
1542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CFreqThreads
1545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1546cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CFreqInfo *Items;
1547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 NumThreads;
1548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CFreqThreads(): Items(0), NumThreads(0) {}
1550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void WaitAll()
1551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt32 i = 0; i < NumThreads; i++)
1553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      Items[i].Wait();
1554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NumThreads = 0;
1555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ~CFreqThreads()
1557cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1558cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    WaitAll();
1559cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    delete []Items;
1560cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1562cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1563cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CCrcInfo
1564cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1565cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NWindows::CThread Thread;
1566cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IBenchPrintCallback *Callback;
1567cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT CallbackRes;
1568cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1569cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const Byte *Data;
1570cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 Size;
1571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 NumIterations;
1572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool CheckSumDefined;
1573cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 CheckSum;
1574cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IHasher> Hasher;
1575cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT Res;
1576cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1577f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #ifdef USE_ALLOCA
1578f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t AllocaSize;
1579f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #endif
1580f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1581cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Wait()
1582cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1583cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Thread.Wait();
1584cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Thread.Close();
1585cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1588cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic THREAD_FUNC_DECL CrcThreadFunction(void *param)
1589cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1590cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCrcInfo *p = (CCrcInfo *)param;
1591f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1592f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #ifdef USE_ALLOCA
1593f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  alloca(p->AllocaSize);
1594f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #endif
1595f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1596cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p->Res = CrcBig(p->Data, p->Size, p->NumIterations,
1597cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      p->CheckSumDefined ? &p->CheckSum : NULL, p->Hasher,
1598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      p->Callback);
1599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return 0;
1600cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1601cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CCrcThreads
1603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1604cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCrcInfo *Items;
1605cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 NumThreads;
1606cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1607cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCrcThreads(): Items(0), NumThreads(0) {}
1608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void WaitAll()
1609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UInt32 i = 0; i < NumThreads; i++)
1611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Items[i].Wait();
1612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NumThreads = 0;
1613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CCrcThreads()
1615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WaitAll();
1617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    delete []Items;
1618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
1620cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
1622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1623baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt32 CrcCalc1(const Byte *buf, UInt32 size)
1624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 crc = CRC_INIT_VAL;;
1626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (UInt32 i = 0; i < size; i++)
1627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    crc = CRC_UPDATE_BYTE(crc, buf[i]);
1628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return CRC_GET_DIGEST(crc);
1629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1631baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
1632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (UInt32 i = 0; i < size; i++)
1634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    buf[i] = (Byte)RG.GetRnd();
1635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1637baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
1638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RandGen(buf, size, RG);
1640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return CrcCalc1(buf, size);
1641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1643baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CrcInternalTest()
1644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchBuffer buffer;
1646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kBufferSize0 = (1 << 8);
1647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kBufferSize1 = (1 << 10);
1648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt32 kCheckSize = (1 << 5);
1649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
1650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
1651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *buf = buffer.Buffer;
1652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
1653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < kBufferSize0; i++)
1654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    buf[i] = (Byte)i;
1655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
1656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (crc1 != 0x29058C73)
1657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
1658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBaseRandomGenerator RG;
1659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RandGen(buf + kBufferSize0, kBufferSize1, RG);
1660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
1661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UInt32 j = 0; j < kCheckSize; j++)
1662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
1663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
1664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
1665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1667cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CBenchMethod
1668cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1669f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned Weight;
1670cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned DictBits;
1671cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 EncComplex;
1672cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 DecComplexCompr;
1673cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 DecComplexUnc;
1674cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const char *Name;
1675cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1677cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const CBenchMethod g_Bench[] =
1678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1679f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 40, 17,  357,  145,   20, "LZMA:x1" },
1680f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 80, 24, 1220,  145,   20, "LZMA:x5:mt1" },
1681f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 80, 24, 1220,  145,   20, "LZMA:x5:mt2" },
1682f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1683f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 16,  124,   40,   14, "Deflate:x1" },
1684f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 20, 16,  376,   40,   14, "Deflate:x5" },
1685f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 16, 1082,   40,   14, "Deflate:x7" },
1686f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 17,  422,   40,   14, "Deflate64:x5" },
1687f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1688f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 15,  590,   69,   69, "BZip2:x1" },
1689f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 20, 19,  815,  122,  122, "BZip2:x5" },
1690f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 19,  815,  122,  122, "BZip2:x5:mt2" },
1691f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 19, 2530,  122,  122, "BZip2:x7" },
1692f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1693f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 18, 1010,    0, 1150, "PPMD:x1" },
1694f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10, 22, 1655,    0, 1830, "PPMD:x5" },
1695f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1696f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {  2,  0,    6,    0,    6, "Delta:4" },
1697f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {  2,  0,    4,    0,    4, "BCJ" },
1698f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1699f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,  0,   24,    0,   24, "AES256CBC:1" },
1700f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {  2,  0,    8,    0,    2, "AES256CBC:2" }
1701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1702cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1703cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CBenchHash
1704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1705f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned Weight;
1706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 Complex;
1707cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 CheckSum;
1708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const char *Name;
1709cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const CBenchHash g_Hash[] =
1712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1713f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {  1,  1820, 0x8F8FEDAB, "CRC32:1" },
1714f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,   558, 0x8F8FEDAB, "CRC32:4" },
1715f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,   339, 0x8F8FEDAB, "CRC32:8" },
1716f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,   512, 0xDF1C17CC, "CRC64" },
1717f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,  5100, 0x2D79FF2E, "SHA256" },
1718f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  { 10,  2340, 0x4C25132B, "SHA1" },
1719f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {  2,  5500, 0xE084E913, "BLAKE2sp" }
1720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1721cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1722cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CTotalBenchRes
1723cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1724f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  // UInt64 NumIterations1; // for Usage
1725f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt64 NumIterations2; // for Rating / RPU
1726f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1727cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 Rating;
1728cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 Usage;
1729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 RPU;
1730f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1731f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; }
1732f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1733cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
1734cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Rating = (r1.Rating + r2.Rating);
1736cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Usage = (r1.Usage + r2.Usage);
1737cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RPU = (r1.RPU + r2.RPU);
1738f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
1739f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    NumIterations2 = (r1.NumIterations2 + r2.NumIterations2);
1740cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1741cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1743f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size)
1744cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1745cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char s[128];
1746f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned startPos = (unsigned)sizeof(s) - 32;
1747cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  memset(s, ' ', startPos);
1748cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertUInt64ToString(value, s + startPos);
1749cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // if (withSpace)
1750cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startPos--;
1752cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size++;
1753cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1754f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned len = (unsigned)strlen(s + startPos);
1755cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size > len)
1756cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1757cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startPos -= (size - len);
1758cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (startPos < 0)
1759cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      startPos = 0;
1760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(s + startPos);
1762cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1764f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_Name = 12;
1765f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_SmallName = 4;
1766f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_Speed = 9;
1767f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_Usage = 5;
1768f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_RU = 6;
1769f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_Rating = 6;
1770f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_EU = 5;
1771f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_Effec = 5;
1772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1773f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating;
1774f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec;
1775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1777f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size)
1778cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1779cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintNumber(f, (rating + 500000) / 1000000, size);
1780cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1781cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1782cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1783f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size)
1784cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1785cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintNumber(f, (val * 100 + divider / 2) / divider, size);
1786cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1787cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1788f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintChars(IBenchPrintCallback &f, char c, unsigned size)
1789cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1790cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char s[256];
1791cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  memset(s, (Byte)c, size);
1792cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s[size] = 0;
1793cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(s);
1794cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1795cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1796f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintSpaces(IBenchPrintCallback &f, unsigned size)
1797cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1798cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintChars(f, ' ', size);
1799cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1800cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1801cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq)
1802cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1803cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintNumber(f, (usage + 5000) / 10000, kFieldSize_Usage);
1804cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintRating(f, rpu, kFieldSize_RU);
1805cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintRating(f, rating, kFieldSize_Rating);
1806cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (showFreq)
1807cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1808cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (cpuFreq == 0)
1809cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintSpaces(f, kFieldSize_EUAndEffec);
1810cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1811cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1812cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 ddd = cpuFreq * usage / 100;
1813cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (ddd == 0)
1814cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ddd = 1;
1815cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU);
1816cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintPercents(f, rating, cpuFreq, kFieldSize_Effec);
1817cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1818cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1819cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1820cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1821f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintResults(IBenchPrintCallback *f,
1822f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const CBenchInfo &info,
1823f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    unsigned weight,
1824f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt64 rating,
1825f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool showFreq, UInt64 cpuFreq,
1826f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CTotalBenchRes *res)
1827cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1828cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations);
1829cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (f)
1830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (speed != 0)
1832cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintNumber(*f, speed / 1024, kFieldSize_Speed);
1833cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1834cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintSpaces(*f, 1 + kFieldSize_Speed);
1835cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1836cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 usage = info.GetUsage();
1837cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 rpu = info.GetRatingPerUsage(rating);
1838cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (f)
1839cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1840cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq);
1841cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1843cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (res)
1844cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1845f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // res->NumIterations1++;
1846f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    res->NumIterations2 += weight;
1847f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    res->RPU += (rpu * weight);
1848f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    res->Rating += (rating * weight);
1849f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    res->Usage += (usage * weight);
1850cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1851cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1853cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res)
1854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1855cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintSpaces(f, 1 + kFieldSize_Speed);
1856f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1;
1857f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1;
1858f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
1859cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1860cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1861f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
1862f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
1863cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1864cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print("RAM ");
1865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(sizeString);
1866f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (size_Defined)
1867f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    PrintNumber(f, (size >> 20), 6);
1868f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  else
1869f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    f.Print("      ?");
1870cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(" MB,  # ");
1871cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(threadsString);
1872cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintNumber(f, numThreads, 3);
1873cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
1874cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1875cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1876cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CBenchCallbackToPrint: public IBenchCallback
1877cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1878cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchProps BenchProps;
1879cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTotalBenchRes EncodeRes;
1880cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTotalBenchRes DecodeRes;
1881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IBenchPrintCallback *_file;
1882cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 DictSize;
1883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool Use2Columns;
1885f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned NameFieldSize;
1886cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool ShowFreq;
1888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 CpuFreq;
1889cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1890f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned EncodeWeight;
1891f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned DecodeWeight;
1892f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1893f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CBenchCallbackToPrint():
1894f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      Use2Columns(false),
1895f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      NameFieldSize(0),
1896f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      ShowFreq(false),
1897f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      CpuFreq(0),
1898f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      EncodeWeight(1),
1899f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      DecodeWeight(1)
1900f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {}
1901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1902cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Init() { EncodeRes.Init(); DecodeRes.Init(); }
1903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Print(const char *s);
1904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void NewLine();
1905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT SetFreq(bool showFreq, UInt64 cpuFreq);
1907cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
1908cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
1909cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
1910cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq)
1912cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ShowFreq = showFreq;
1914cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CpuFreq = cpuFreq;
1915cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
1916cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1917cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1918cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
1919cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1920cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(_file->CheckBreak());
1921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (final)
1922cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations);
1924f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    PrintResults(_file, info,
1925f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        EncodeWeight, rating,
1926f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        ShowFreq, CpuFreq, &EncodeRes);
1927f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (!Use2Columns)
1928f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      _file->NewLine();
1929cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1930cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
1931cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1932cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1933cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const char *kSep = "  | ";
1934cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1935cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
1936cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1937cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(_file->CheckBreak());
1938cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (final)
1939cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1940cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
1941cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (Use2Columns)
1942cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _file->Print(kSep);
1943cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1944cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintSpaces(*_file, NameFieldSize);
1945cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CBenchInfo info2 = info;
1946cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    info2.UnpackSize *= info2.NumIterations;
1947cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    info2.PackSize *= info2.NumIterations;
1948cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    info2.NumIterations = 1;
1949f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    PrintResults(_file, info2,
1950f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        DecodeWeight, rating,
1951f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        ShowFreq, CpuFreq, &DecodeRes);
1952cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1953cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
1954cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1955cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1956cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CBenchCallbackToPrint::Print(const char *s)
1957cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1958cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _file->Print(s);
1959cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1960cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1961cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CBenchCallbackToPrint::NewLine()
1962cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1963cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _file->NewLine();
1964cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1965cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1966cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size)
1967cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1968cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(s);
1969cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int numSpaces = size - MyStringLen(s);
1970cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numSpaces > 0)
1971cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintSpaces(f, numSpaces);
1972cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1973cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1974cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid PrintRight(IBenchPrintCallback &f, const char *s, unsigned size)
1975cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1976cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int numSpaces = size - MyStringLen(s);
1977cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numSpaces > 0)
1978cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintSpaces(f, numSpaces);
1979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.Print(s);
1980cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
1981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1982cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT TotalBench(
1983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    DECL_EXTERNAL_CODECS_LOC_VARS
1984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 complexInCommands,
1985f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32 numThreads,
1986f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bool forceUnpackSize,
1987f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    size_t unpackSize,
1988f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const Byte *fileData,
1989f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
1990cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
1991cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
1992cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1993f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const CBenchMethod &bench = g_Bench[i];
1994cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
1995cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
1996cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
1997cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback->BenchProps.EncComplex = bench.EncComplex;
1998f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COneMethodInfo method;
2000cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NCOM::CPropVariant propVariant;
2001cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    propVariant = bench.Name;
2002f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
2003cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2004f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    size_t unpackSize2 = unpackSize;
2005cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!forceUnpackSize && bench.DictBits == 0)
2006cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unpackSize2 = kFilterUnpackSize;
2007cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2008f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    callback->EncodeWeight = bench.Weight;
2009f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    callback->DecodeWeight = bench.Weight;
2010f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2011cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res = MethodBench(
2012cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        EXTERNAL_CODECS_LOC_VARS
2013cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        complexInCommands,
2014f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        false, numThreads, method,
2015f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        unpackSize2, fileData,
2016f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        bench.DictBits,
2017cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        printCallback, callback, &callback->BenchProps);
2018f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (res == E_NOTIMPL)
2020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2021cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // callback->Print(" ---");
2022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // we need additional empty line as line for decompression results
2023cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!callback->Use2Columns)
2024cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        callback->NewLine();
2025cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2026cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
2027cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2028cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(res);
2029cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2030f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2031cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback->NewLine();
2032cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2033cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
2034cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2035cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2036cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2037cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT FreqBench(
2038cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 complexInCommands,
2039cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numThreads,
2040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *_file,
2041cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool showFreq,
2042f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt64 specifiedFreq,
2043cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 &cpuFreq,
2044cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 &res)
2045cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2046cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  res = 0;
2047cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  cpuFreq = 0;
2048cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2049cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 bufferSize = 1 << 20;
2050cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 complexity = kNumFreqCommands;
2051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numThreads == 0)
2052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numThreads = 1;
2053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
2054cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef _7ZIP_ST
2055cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  numThreads = 1;
2056cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
2057cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2058cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
2059cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 numIterations = complexInCommands / complexity / bsize;
2060cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numIterations == 0)
2061cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numIterations = 1;
2062cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2063cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfoCalc progressInfoSpec;
2064cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2065cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifndef _7ZIP_ST
2066cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CFreqThreads threads;
2067cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numThreads > 1)
2068cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2069cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    threads.Items = new CFreqInfo[numThreads];
2070cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 i;
2071cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < numThreads; i++)
2072cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2073cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CFreqInfo &info = threads.Items[i];
2074cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.Callback = _file;
2075cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.CallbackRes = S_OK;
2076cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.NumIterations = numIterations;
2077cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.Size = bufferSize;
2078cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2079cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    progressInfoSpec.SetStartTime();
2080cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < numThreads; i++)
2081cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2082cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CFreqInfo &info = threads.Items[i];
2083cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(info.Thread.Create(FreqThreadFunction, &info));
2084cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      threads.NumThreads++;
2085cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2086cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    threads.WaitAll();
2087cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < numThreads; i++)
2088cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2089cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(threads.Items[i].CallbackRes);
2090cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2091cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2092cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
2093cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
2094cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2095cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    progressInfoSpec.SetStartTime();
2096cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 sum = g_BenchCpuFreqTemp;
2097cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt64 k = numIterations; k > 0; k--)
2098cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2099cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(_file->CheckBreak());
2100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      sum = CountCpuFreq(sum, bufferSize, g_BenchCpuFreqTemp);
2101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    res += sum;
2103cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2104f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfo info;
2106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  progressInfoSpec.SetFinishTime(info);
2107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.UnpackSize = 0;
2109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.PackSize = 0;
2110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.NumIterations = 1;
2111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_file)
2113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 numCommands = (UInt64)numIterations * bufferSize * numThreads * complexity;
2116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 rating = info.GetSpeed(numCommands);
2117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      cpuFreq = rating / numThreads;
2118f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      PrintResults(_file, info,
2119f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          0, // weight
2120f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          rating,
2121f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL);
2122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(_file->CheckBreak());
2124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
2127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT CrcBench(
2132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    DECL_EXTERNAL_CODECS_LOC_VARS
2133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 complexInCommands,
2134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numThreads, UInt32 bufferSize,
2135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 &speed,
2136f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt32 complexity, unsigned benchWeight,
2137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UInt32 *checkSum,
2138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const COneMethodInfo &method,
2139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *_file,
2140cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CTotalBenchRes *encodeRes,
2141cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool showFreq, UInt64 cpuFreq)
2142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numThreads == 0)
2144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numThreads = 1;
2145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef _7ZIP_ST
2147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  numThreads = 1;
2148cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
2149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2150f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  AString methodName = method.MethodName;
2151cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // methodName.RemoveChar(L'-');
2152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMethodId hashID;
2153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!FindHashMethod(
2154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      EXTERNAL_CODECS_LOC_VARS
2155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      methodName, hashID))
2156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_NOTIMPL;
2157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBenchBuffer buffer;
2159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t totalSize = (size_t)bufferSize * numThreads;
2160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (totalSize / numThreads != bufferSize)
2161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_OUTOFMEMORY;
2162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!buffer.Alloc(totalSize))
2163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_OUTOFMEMORY;
2164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
2165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *buf = buffer.Buffer;
2166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBaseRandomGenerator RG;
2167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
2168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 numIterations = complexInCommands * 256 / complexity / bsize;
2169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numIterations == 0)
2170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numIterations = 1;
2171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfoCalc progressInfoSpec;
2173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
2174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
2175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CCrcThreads threads;
2176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numThreads > 1)
2177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
2178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    threads.Items = new CCrcInfo[numThreads];
2179f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 i;
2181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numThreads; i++)
2182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
2183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CCrcInfo &info = threads.Items[i];
2184f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      AString name;
2185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, info.Hasher));
2186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!info.Hasher)
2187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_NOTIMPL;
2188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CMyComPtr<ICompressSetCoderProperties> scp;
2189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
2190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (scp)
2191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt64 reduceSize = 1;
2193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(method.SetCoderProps(scp, &reduceSize));
2194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2195cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte *data = buf + (size_t)bufferSize * i;
2197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.Callback = _file;
2198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      info.Data = data;
2199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.NumIterations = numIterations;
2200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      info.Size = bufferSize;
2201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /* info.Crc = */ RandGenCrc(data, bufferSize, RG);
2202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      info.CheckSumDefined = false;
2203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (checkSum)
2204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        info.CheckSum = *checkSum;
2206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        info.CheckSumDefined = (checkSum && (i == 0));
2207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2208f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2209f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #ifdef USE_ALLOCA
2210f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      info.AllocaSize = (i * 16 * 21) & 0x7FF;
2211f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #endif
2212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
2213f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    progressInfoSpec.SetStartTime();
2215f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numThreads; i++)
2217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
2218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CCrcInfo &info = threads.Items[i];
2219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(info.Thread.Create(CrcThreadFunction, &info));
2220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      threads.NumThreads++;
2221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
2222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    threads.WaitAll();
2223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numThreads; i++)
2224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2225cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(threads.Items[i].Res);
2226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
2228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
2229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
2230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
2231cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /* UInt32 crc = */ RandGenCrc(buf, bufferSize, RG);
2232cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    progressInfoSpec.SetStartTime();
2233cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<IHasher> hasher;
2234f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    AString name;
2235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher));
2236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!hasher)
2237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
2238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<ICompressSetCoderProperties> scp;
2239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
2240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (scp)
2241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 reduceSize = 1;
2243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(method.SetCoderProps(scp, &reduceSize));
2244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(CrcBig(buf, bufferSize, numIterations, checkSum, hasher, _file));
2246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2247f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchInfo info;
2249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  progressInfoSpec.SetFinishTime(info);
2250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 unpSize = numIterations * bufferSize;
2252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 unpSizeThreads = unpSize * numThreads;
2253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.UnpackSize = unpSizeThreads;
2254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.PackSize = unpSizeThreads;
2255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  info.NumIterations = 1;
2256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_file)
2258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 numCommands = unpSizeThreads * complexity / 256;
2261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 rating = info.GetSpeed(numCommands);
2262f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      PrintResults(_file, info,
2263f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          benchWeight, rating,
2264f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          showFreq, cpuFreq, encodeRes);
2265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2266cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(_file->CheckBreak());
2267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  speed = info.GetSpeed(unpSizeThreads);
2270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
2272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT TotalBench_Hash(
2275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    DECL_EXTERNAL_CODECS_LOC_VARS
2276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 complexInCommands,
2277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numThreads, UInt32 bufSize,
2278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback,
2279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CTotalBenchRes *encodeRes,
2280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool showFreq, UInt64 cpuFreq)
2281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
2283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CBenchHash &bench = g_Hash[i];
2285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintLeft(*callback->_file, bench.Name, kFieldSize_Name);
2286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
2287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
2288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // callback->BenchProps.EncComplex = bench.EncComplex;
2289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COneMethodInfo method;
2291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NCOM::CPropVariant propVariant;
2292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    propVariant = bench.Name;
2293f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant));
2294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 speed;
2296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res = CrcBench(
2297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        EXTERNAL_CODECS_LOC_VARS
2298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        complexInCommands,
2299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numThreads, bufSize,
2300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        speed,
2301f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        bench.Complex, bench.Weight,
2302f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        &bench.CheckSum, method,
2303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        printCallback, encodeRes, showFreq, cpuFreq);
2304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (res == E_NOTIMPL)
2305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // callback->Print(" ---");
2307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
2309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(res);
2311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback->NewLine();
2313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
2315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CTempValues
2318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 *Values;
2320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTempValues(UInt32 num) { Values = new UInt64[num]; }
2321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ~CTempValues() { delete []Values; }
2322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
2323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
2325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const wchar_t *end;
2327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 result = ConvertStringToUInt64(s, &end);
2328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (*end != 0 || s.IsEmpty())
2329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop = s;
2330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else if (result <= (UInt32)0xFFFFFFFF)
2331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop = (UInt32)result;
2332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
2333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop = result;
2334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2336cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads)
2337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (i < 2)
2339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return i + 1;
2340cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  i -= 1;
2341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 num = (UInt32)(2 + (i & 1)) << (i >> 1);
2342cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (num <= numThreads) ? num : numThreads;
2343cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2344cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2345f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic bool AreSameMethodNames(const char *fullName, const char *shortName)
2346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (;;)
2348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2349f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    char c2 = *shortName++;
2350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c2 == 0)
2351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return true;
2352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    char c1 = *fullName++;
2353f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
2354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return false;
2355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
2357cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2358f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2359f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#ifdef MY_CPU_X86_OR_AMD64
2360f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2361f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void PrintCpuChars(AString &s, UInt32 v)
2362f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{
2363f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  for (int j = 0; j < 4; j++)
2364f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2365f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Byte b = (Byte)(v & 0xFF);
2366f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    v >>= 8;
2367f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (b == 0)
2368f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      break;
2369f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s += (char)b;
2370f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2371f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka}
2372f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2373f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
2374f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{
2375f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  s.Empty();
2376f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2377f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 maxFunc2 = 0;
2378f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 t[3];
2379f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2380f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]);
2381f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2382f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool fullNameIsAvail = (maxFunc2 >= 0x80000004);
2383f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2384f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (!fullNameIsAvail)
2385f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2386f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    for (int i = 0; i < 3; i++)
2387f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      PrintCpuChars(s, c.vendor[i]);
2388f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2389f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  else
2390f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2391f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    for (int i = 0; i < 3; i++)
2392f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2393f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt32 d[4] = { 0 };
2394f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      MyCPUID(0x80000002 + i, &d[0], &d[1], &d[2], &d[3]);
2395f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      for (int j = 0; j < 4; j++)
2396f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        PrintCpuChars(s, d[j]);
2397f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2398f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2399f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2400f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  s.Add_Space_if_NotEmpty();
2401f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2402f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    char temp[32];
2403f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ConvertUInt32ToHex(c.ver, temp);
2404f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s += '(';
2405f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s += temp;
2406f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s += ')';
2407f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2408f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka}
2409f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#endif
2411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2412f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2413f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakavoid GetCpuName(AString &s)
2414f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{
2415f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  s.Empty();
2416f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2417f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #ifdef MY_CPU_X86_OR_AMD64
2418f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2419f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    Cx86cpuid cpuid;
2420f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (x86cpuid_CheckAndRead(&cpuid))
2421f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2422f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      x86cpuid_to_String(cpuid, s);
2423f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      return;
2424f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2425f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #ifdef MY_CPU_AMD64
2426f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s = "x64";
2427f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #else
2428f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    s = "x86";
2429f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #endif
2430f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2431f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #else
2432f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2433f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #ifdef MY_CPU_LE
2434f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      s = "LE";
2435f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #elif defined(MY_CPU_BE)
2436f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      s = "BE";
2437f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #endif
2438f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2439f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  #endif
2440f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka}
2441f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2442f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT Bench(
2444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    DECL_EXTERNAL_CODECS_LOC_VARS
2445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback *printCallback,
2446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchCallback *benchCallback,
2447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CObjectVector<CProperty> &props,
2448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numIterations,
2449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool multiDict)
2450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
2451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!CrcInternalTest())
2452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
2453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 numCPUs = 1;
2455f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
2456f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifndef _7ZIP_ST
2458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  numCPUs = NSystem::GetNumberOfProcessors();
2459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
2460f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2461f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool ramSize_Defined = NSystem::GetRamSize(ramSize);
2462f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2463f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numThreadsSpecified = numCPUs;
2464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 testTime = kComplexInSeconds;
2466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2467f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt64 specifiedFreq = 0;
2468f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2469f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool multiThreadTests = false;
2470f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  COneMethodInfo method;
2472f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2473f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CBenchBuffer fileDataBuffer;
2474f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2475f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
2477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < props.Size(); i++)
2478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CProperty &property = props[i];
2480cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString name = property.Name;
2481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    name.MakeLower_Ascii();
2482f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2483f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (name.IsEqualTo("file"))
2484f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2485f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (property.Value.IsEmpty())
2486f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_INVALIDARG;
2487f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2488f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #ifdef USE_WIN_FILE
2489f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2490f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      NFile::NIO::CInFile file;
2491f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (!file.Open(us2fs(property.Value)))
2492f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_INVALIDARG;
2493f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt64 len;
2494f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (!file.GetLength(len))
2495f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_FAIL;
2496f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (len >= ((UInt32)1 << 31) || len == 0)
2497f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_INVALIDARG;
2498f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (!fileDataBuffer.Alloc((size_t)len))
2499f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_OUTOFMEMORY;
2500f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt32 processedSize;
2501f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize);
2502f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (processedSize != len)
2503f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_FAIL;
2504f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (printCallback)
2505f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2506f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        printCallback->Print("file size =");
2507f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        // printCallback->Print(GetOemString(property.Value));
2508f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        PrintNumber(*printCallback, len, 0);
2509f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        printCallback->NewLine();
2510f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2511f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      continue;
2512f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2513f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #else
2514f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2515f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      return E_NOTIMPL;
2516f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2517f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      #endif
2518f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2519f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2520f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    NCOM::CPropVariant propVariant;
2521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!property.Value.IsEmpty())
2522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ParseNumberString(property.Value, propVariant);
2523f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2524f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (name.IsEqualTo("time"))
2525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(ParsePropToUInt32(L"", propVariant, testTime));
2527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
2528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2529f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2530f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (name.IsEqualTo("freq"))
2531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2532f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt32 freq32 = 0;
2533f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(ParsePropToUInt32(L"", propVariant, freq32));
2534f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (freq32 == 0)
2535f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        return E_INVALIDARG;
2536f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      specifiedFreq = (UInt64)freq32 * 1000000;
2537f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2538f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (printCallback)
2539f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2540f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        printCallback->Print("freq=");
2541f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        PrintNumber(*printCallback, freq32, 0);
2542f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        printCallback->NewLine();
2543f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2544f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2545f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      continue;
2546f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2547f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2548f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (name.IsPrefixedBy_Ascii_NoCase("mt"))
2549f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2550f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UString s = name.Ptr(2);
2551f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (s == L"*")
2552f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2553f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        multiThreadTests = true;
2554f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        continue;
2555f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2556f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (s.IsEmpty() && propVariant.vt == VT_BSTR)
2557f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2558f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (wcscmp(propVariant.bstrVal, L"*") == 0)
2559f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        {
2560f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          multiThreadTests = true;
2561f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          continue;
2562f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        }
2563f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2564cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #ifndef _7ZIP_ST
2565f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified));
2566cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #endif
2567cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
2568cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2569f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2570cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant));
2571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2572f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2573f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2574f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (printCallback)
2575f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2576f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    AString s;
2577f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    GetCpuName(s);
2578f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    printCallback->Print(s);
2579f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    printCallback->NewLine();
2580f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2581cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2582cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (printCallback)
2583cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2584cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    printCallback->Print("CPU Freq:");
2585cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 complexInCommands = kComplexInCommands;
2588cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2589f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (printCallback /* || benchCallback */)
2590cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2591f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    UInt64 numMilCommands = 1 << 6;
2592f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (specifiedFreq != 0)
2593f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2594f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000))
2595f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        numMilCommands >>= 1;
2596f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2597cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (int jj = 0;; jj++)
2599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2600f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (printCallback)
2601f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        RINOK(printCallback->CheckBreak());
2602f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 start = ::GetTimeCount();
2604cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 sum = (UInt32)start;
2605cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
2606f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      const UInt64 realDelta = ::GetTimeCount() - start;
2607f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      start = realDelta;
2608cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (start == 0)
2609cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        start = 1;
2610cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 freq = GetFreq();
2611f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      // mips is constant in some compilers
2612f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      const UInt64 mipsVal = numMilCommands * freq / start;
2613cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (printCallback)
2614f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2615f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (realDelta == 0)
2616f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        {
2617f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          printCallback->Print(" -");
2618f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        }
2619f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        else
2620f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        {
2621f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          // PrintNumber(*printCallback, start, 0);
2622f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
2623f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        }
2624f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2625f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      /*
2626f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (benchCallback)
2627f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        benchCallback->AddCpuFreq(mipsVal);
2628f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      */
2629f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2630cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (jj >= 3)
2631cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2632f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        SetComplexCommands(testTime, false, mipsVal * 1000000, complexInCommands);
2633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (jj >= 8 || start >= freq)
2634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          break;
2635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // break; // change it
2636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numMilCommands <<= 1;
2637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2640f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2641cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (printCallback)
2642cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2643cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    printCallback->NewLine();
2644cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    printCallback->NewLine();
2645f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
2646cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2647cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2648f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
2649cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_INVALIDARG;
2650cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2651cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 dict;
2652cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool dictIsDefined = method.Get_DicSize(dict);
2653cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2654cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (method.MethodName.IsEmpty())
2655f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    method.MethodName = "LZMA";
2656cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2657cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (benchCallback)
2658cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2659cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CBenchProps benchProps;
2660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    benchProps.SetLzmaCompexity();
2661cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 dictSize = method.Get_Lzma_DicSize();
2662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 uncompressedDataSize = kAdditionalSize + dictSize;
2663cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return MethodBench(
2664cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        EXTERNAL_CODECS_LOC_VARS
2665cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        complexInCommands,
2666f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        true, numThreadsSpecified,
2667f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        method,
2668f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        uncompressedDataSize, fileDataBuffer.Buffer,
2669cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
2670cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2671cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2672f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  AString methodName = method.MethodName;
2673f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
2674f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    methodName = "crc32";
2675cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  method.MethodName = methodName;
2676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMethodId hashID;
2677f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID))
2679cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2680cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!printCallback)
2681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_FALSE;
2682cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IBenchPrintCallback &f = *printCallback;
2683cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!dictIsDefined)
2684cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dict = (1 << 24);
2685cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2686cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2687cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // methhodName.RemoveChar(L'-');
2688cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 complexity = 10000;
2689cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UInt32 *checkSum = NULL;
2690cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2691cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
2692cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2693cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        const CBenchHash &h = g_Hash[i];
2694f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        AString s = h.Name;
2695f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        AString hProp;
2696f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        int propPos = s.Find(':');
2697f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (propPos >= 0)
2698f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        {
2699f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          hProp = s.Ptr(propPos + 1);
2700f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          s.DeleteFrom(propPos);
2701f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        }
2702f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2703f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (AreSameMethodNames(s, methodName))
2704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
2705cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          complexity = h.Complex;
2706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          checkSum = &h.CheckSum;
2707f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp))
2708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            break;
2709cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
2710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2713cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.NewLine();
2714cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.Print("Size");
2715f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const unsigned kFieldSize_CrcSpeed = 6;
2716cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned numThreadsTests = 0;
2717cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (;;)
2718cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2719f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt32 t = GetNumThreadsNext(numThreadsTests, numThreadsSpecified);
2720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintNumber(f, t, kFieldSize_CrcSpeed);
2721cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      numThreadsTests++;
2722f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (t >= numThreadsSpecified)
2723cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
2724cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2725cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.NewLine();
2726cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.NewLine();
2727cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CTempValues speedTotals(numThreadsTests);
2728cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned ti = 0; ti < numThreadsTests; ti++)
2730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        speedTotals.Values[ti] = 0;
2731cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2732cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2733cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 numSteps = 0;
2734cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt32 i = 0; i < numIterations; i++)
2735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2736cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned pow = 10; pow < 32; pow++)
2737cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2738cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 bufSize = (UInt32)1 << pow;
2739cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (bufSize > dict)
2740cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          break;
2741cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        char s[16];
2742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ConvertUInt32ToString(pow, s);
2743f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        unsigned pos = MyStringLen(s);
2744cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        s[pos++] = ':';
2745cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        s[pos++] = ' ';
2746cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        s[pos] = 0;
2747cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        f.Print(s);
2748cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2749cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (unsigned ti = 0; ti < numThreadsTests; ti++)
2750cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
2751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          RINOK(f.CheckBreak());
2752f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          UInt32 t = GetNumThreadsNext(ti, numThreadsSpecified);
2753cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          UInt64 speed = 0;
2754cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          RINOK(CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands,
2755f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka              t, bufSize, speed,
2756f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka              complexity,
2757f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka              1, // benchWeight,
2758cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              (pow == kNumHashDictBits) ? checkSum : NULL, method, NULL, NULL, false, 0));
2759cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          PrintNumber(f, (speed >> 20), kFieldSize_CrcSpeed);
2760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          speedTotals.Values[ti] += speed;
2761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
2762cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        f.NewLine();
2763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numSteps++;
2764cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2765cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2766cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (numSteps != 0)
2767cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2768cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.NewLine();
2769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.Print("Avg:");
2770cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned ti = 0; ti < numThreadsTests; ti++)
2771cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), kFieldSize_CrcSpeed);
2773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.NewLine();
2775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_OK;
2777cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2778cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2779cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool use2Columns = false;
2780cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2781f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*"));
2782f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  bool onlyHashBench = false;
2783f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (method.MethodName.IsEqualTo_Ascii_NoCase("hash"))
2784f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2785f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    onlyHashBench = true;
2786f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    totalBenchMode = true;
2787f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2788f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2789f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  // ---------- Threads loop ----------
2790f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++)
2791f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2792f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2793f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numThreads = numThreadsSpecified;
2794f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2795f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (!multiThreadTests)
2796f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2797f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (threadsPassIndex != 0)
2798f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      break;
2799f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2800f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  else
2801f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2802f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    numThreads = 1;
2803f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (threadsPassIndex != 0)
2804f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2805f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (numCPUs < 2)
2806f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        break;
2807f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      numThreads = numCPUs;
2808f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (threadsPassIndex == 1)
2809f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2810f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (numCPUs >= 4)
2811f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          numThreads = numCPUs / 2;
2812f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2813f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      else if (numCPUs < 4)
2814f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        break;
2815f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2816f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2817f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2818cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CBenchCallbackToPrint callback;
2819cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  callback.Init();
2820cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  callback._file = printCallback;
2821f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2822f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  IBenchPrintCallback &f = *printCallback;
2823f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2824f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (threadsPassIndex > 0)
2825f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  {
2826f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    f.NewLine();
2827f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    f.NewLine();
2828f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
2829cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!dictIsDefined)
2831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2832f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
2833f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    unsigned dicSizeLog = dicSizeLog_Main;
2834f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2835f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #ifdef UNDER_CE
2836f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    dicSizeLog = (UInt64)1 << 20;
2837f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    #endif
2838f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2839f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (ramSize_Defined)
2840f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
2841f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize)
2842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
2843f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2844f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    dict = (UInt32)1 << dicSizeLog;
2845f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2846f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (totalBenchMode && dicSizeLog != dicSizeLog_Main)
2847f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    {
2848f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      f.Print("Dictionary reduced to: ");
2849f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      PrintNumber(f, dicSizeLog, 1);
2850f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      f.NewLine();
2851f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    }
2852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2853cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2854f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads:   ", numThreads);
2855cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2856cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
2857cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2858cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (totalBenchMode)
2859cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2860cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback.NameFieldSize = kFieldSize_Name;
2861cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    use2Columns = false;
2862cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2863cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
2864cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    callback.NameFieldSize = kFieldSize_SmallName;
2866cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    use2Columns = true;
2867cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2868cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  callback.Use2Columns = use2Columns;
2869cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2870cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool showFreq = false;
2871cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 cpuFreq = 0;
2872cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2873cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (totalBenchMode)
2874cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2875cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    showFreq = true;
2876cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2877cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2878f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned fileldSize = kFieldSize_TotalSize;
2879cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (showFreq)
2880cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    fileldSize += kFieldSize_EUAndEffec;
2881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2882cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (use2Columns)
2883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintSpaces(f, callback.NameFieldSize);
2885cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "Compressing", fileldSize);
2886cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.Print(kSep);
2887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "Decompressing", fileldSize);
2888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2889cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
2890cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize);
2891cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2892cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int j;
2893cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2894cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (j = 0; j < 2; j++)
2895cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2896cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "Speed", kFieldSize_Speed + 1);
2897cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "Usage", kFieldSize_Usage + 1);
2898cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "R/U", kFieldSize_RU + 1);
2899cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "Rating", kFieldSize_Rating + 1);
2900cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (showFreq)
2901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2902cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintRight(f, "E/U", kFieldSize_EU + 1);
2903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintRight(f, "Effec", kFieldSize_Effec + 1);
2904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!use2Columns)
2906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      break;
2907cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (j == 0)
2908cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.Print(kSep);
2909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
2910cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
2912cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintSpaces(f, callback.NameFieldSize);
2913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2914cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (j = 0; j < 2; j++)
2915cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2916f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    PrintRight(f, "KiB/s", kFieldSize_Speed + 1);
2917cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "%", kFieldSize_Usage + 1);
2918cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "MIPS", kFieldSize_RU + 1);
2919cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintRight(f, "MIPS", kFieldSize_Rating + 1);
2920cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (showFreq)
2921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2922cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintRight(f, "%", kFieldSize_EU + 1);
2923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintRight(f, "%", kFieldSize_Effec + 1);
2924cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2925cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!use2Columns)
2926cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      break;
2927cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (j == 0)
2928cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.Print(kSep);
2929cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2930cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2931cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
2932cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
2933baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
2934f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (specifiedFreq != 0)
2935f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    cpuFreq = specifiedFreq;
2936f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2937f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2938cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (totalBenchMode)
2939cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2940cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt32 i = 0; i < numIterations; i++)
2941cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
2942cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (i != 0)
2943cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        printCallback->NewLine();
2944cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      HRESULT res;
2945cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2946f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      const unsigned kNumCpuTests = 3;
2947f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++)
2948cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2949cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        PrintLeft(f, "CPU", kFieldSize_Name);
2950cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 resVal;
2951f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        RINOK(FreqBench(complexInCommands, numThreads, printCallback,
2952f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            (freqTest == kNumCpuTests - 1 || specifiedFreq != 0), // showFreq
2953f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            specifiedFreq,
2954f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            cpuFreq, resVal));
2955cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        callback.NewLine();
2956cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2957f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (specifiedFreq != 0)
2958f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          cpuFreq = specifiedFreq;
2959f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2960cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (freqTest == kNumCpuTests - 1)
2961f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          SetComplexCommands(testTime, specifiedFreq != 0, cpuFreq, complexInCommands);
2962cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2963cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      callback.NewLine();
2964cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2965cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      callback.SetFreq(true, cpuFreq);
2966f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
2967f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (!onlyHashBench)
2968f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
2969f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        res = TotalBench(EXTERNAL_CODECS_LOC_VARS
2970f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            complexInCommands, numThreads,
2971f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize
2972f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict,
2973f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            fileDataBuffer.Buffer,
2974f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            printCallback, &callback);
2975f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        RINOK(res);
2976f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
2977cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2978cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads,
2979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          1 << kNumHashDictBits, printCallback, &callback, &callback.EncodeRes, true, cpuFreq);
2980cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(res);
2981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
2982cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      callback.NewLine();
2983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
2984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        PrintLeft(f, "CPU", kFieldSize_Name);
2985cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 resVal;
2986cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt64 cpuFreqLastTemp = cpuFreq;
2987f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        RINOK(FreqBench(complexInCommands, numThreads, printCallback,
2988f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            specifiedFreq != 0, // showFreq
2989f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            specifiedFreq,
2990f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            cpuFreqLastTemp, resVal));
2991cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        callback.NewLine();
2992cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
2993cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
2994cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
2995cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
2996cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
2997cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool needSetComplexity = true;
2998f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
2999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
3000cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
3001cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
3002cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        const CBenchMethod &h = g_Bench[i];
3003cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        AString s = h.Name;
3004cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (AreSameMethodNames(h.Name, methodName))
3005cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
3006cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          callback.BenchProps.EncComplex = h.EncComplex;
3007cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
3008cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          callback.BenchProps.DecComplexUnc = h.DecComplexUnc;;
3009cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          needSetComplexity = false;
3010cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          break;
3011cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
3012cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
3013cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
3014cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (needSetComplexity)
3015cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      callback.BenchProps.SetLzmaCompexity();
3016cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3017f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  for (unsigned i = 0; i < numIterations; i++)
3018cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
3019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const unsigned kStartDicLog = 22;
3020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
3021cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!multiDict)
3022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      pow = 31;
3023cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    while (((UInt32)1 << pow) > dict && pow > 0)
3024cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      pow--;
3025cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (; ((UInt32)1 << pow) <= dict; pow++)
3026cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
3027cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      char s[16];
3028cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ConvertUInt32ToString(pow, s);
3029cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned pos = MyStringLen(s);
3030cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s[pos++] = ':';
3031cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s[pos] = 0;
3032cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintLeft(f, s, kFieldSize_SmallName);
3033cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      callback.DictSize = (UInt32)1 << pow;
3034cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3035cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      COneMethodInfo method2 = method;
3036cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3037f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA"))
3038cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
3039cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // We add dictionary size property.
3040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // method2 can have two different dictionary size properties.
3041cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // And last property is main.
3042cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        NCOM::CPropVariant propVariant = (UInt32)pow;
3043cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant));
3044cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
3045cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3046f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      size_t uncompressedDataSize;
3047f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (fileDataBuffer.Buffer)
3048f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
3049f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        uncompressedDataSize = fileDataBuffer.BufferSize;
3050f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
3051f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      else
3052f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      {
3053f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        uncompressedDataSize = callback.DictSize;
3054f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (uncompressedDataSize >= (1 << 18))
3055f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          uncompressedDataSize += kAdditionalSize;
3056f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      }
3057cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3058cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      HRESULT res = MethodBench(
3059cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          EXTERNAL_CODECS_LOC_VARS
3060cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          complexInCommands,
3061cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          true, numThreads,
3062f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          method2,
3063f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          uncompressedDataSize, fileDataBuffer.Buffer,
3064cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
3065cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.NewLine();
3066cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(res);
3067cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!multiDict)
3068cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
3069cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
3070cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
3071cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
3072cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3073cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintChars(f, '-', callback.NameFieldSize + fileldSize);
3074cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3075cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (use2Columns)
3076cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
3077cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.Print(kSep);
3078cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintChars(f, '-', fileldSize);
3079cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
3080f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
3081cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
3082f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
3083cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (use2Columns)
3084cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
3085cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintLeft(f, "Avr:", callback.NameFieldSize);
3086cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes);
3087cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.Print(kSep);
3088cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes);
3089cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.NewLine();
3090cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
3091f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
3092cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintLeft(f, "Tot:", callback.NameFieldSize);
3093cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTotalBenchRes midRes;
3094cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  midRes.SetSum(callback.EncodeRes, callback.DecodeRes);
3095cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PrintTotals(f, showFreq, cpuFreq, midRes);
3096cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NewLine();
3097f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
3098f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  }
3099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
3100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
3101