Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / Compress / LZMA_Alone / LzmaBenchCon.cpp
1 // LzmaBenchCon.cpp
2
3 #include "StdAfx.h"
4
5 #include <stdio.h>
6
7 #include "LzmaBench.h"
8 #include "LzmaBenchCon.h"
9 #include "../../../Common/IntToString.h"
10
11 #if defined(BENCH_MT) || defined(_WIN32)
12 #include "../../../Windows/System.h"
13 #endif
14
15 #ifdef BREAK_HANDLER
16 #include "../../UI/Console/ConsoleClose.h"
17 #endif
18 #include "../../../Common/MyCom.h"
19
20 struct CTotalBenchRes
21 {
22   UInt64 NumIterations;
23   UInt64 Rating;
24   UInt64 Usage;
25   UInt64 RPU;
26   void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
27   void Normalize() 
28   { 
29     if (NumIterations == 0) 
30       return;
31     Rating /= NumIterations; 
32     Usage /= NumIterations; 
33     RPU /= NumIterations; 
34     NumIterations = 1;
35   }
36   void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2) 
37   { 
38     Rating = (r1.Rating + r2.Rating) / 2; 
39     Usage = (r1.Usage + r2.Usage) / 2;
40     RPU = (r1.RPU + r2.RPU) / 2;
41     NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
42   }
43 };
44
45 struct CBenchCallback: public IBenchCallback
46 {
47   CTotalBenchRes EncodeRes;
48   CTotalBenchRes DecodeRes;
49   FILE *f;
50   void Init() { EncodeRes.Init(); DecodeRes.Init(); }
51   void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
52   UInt32 dictionarySize;
53   HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
54   HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
55 };
56
57 static void NormalizeVals(UInt64 &v1, UInt64 &v2)
58 {
59   while (v1 > 1000000)
60   {
61     v1 >>= 1;
62     v2 >>= 1;
63   }
64 }
65
66 static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
67 {
68   UInt64 elTime = elapsedTime;
69   NormalizeVals(freq, elTime);
70   if (elTime == 0)
71     elTime = 1;
72   return value * freq / elTime;
73 }
74
75 static void PrintNumber(FILE *f, UInt64 value, int size)
76 {
77   char s[32];
78   ConvertUInt64ToString(value, s);
79   fprintf(f, " ");
80   for (int len = (int)strlen(s); len < size; len++)
81     fprintf(f, " ");
82   fprintf(f, "%s", s);
83 }
84
85 static void PrintRating(FILE *f, UInt64 rating)
86 {
87   PrintNumber(f, rating / 1000000, 6);
88 }
89
90 static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)
91 {
92   PrintNumber(f, (usage + 5000) / 10000, 5);
93   PrintRating(f, rpu);
94   PrintRating(f, rating);
95 }
96
97
98 static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
99 {
100   UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
101   PrintNumber(f, speed / 1024, 7);
102   UInt64 usage = GetUsage(info);
103   UInt64 rpu = GetRatingPerUsage(info, rating);
104   PrintResults(f, usage, rpu, rating);
105   res.NumIterations++;
106   res.RPU += rpu;
107   res.Rating += rating;
108   res.Usage += usage;
109 }
110
111 static void PrintTotals(FILE *f, const CTotalBenchRes &res)
112 {
113   fprintf(f, "       ");
114   PrintResults(f, res.Usage, res.RPU, res.Rating);
115 }
116
117
118 HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
119 {
120   #ifdef BREAK_HANDLER
121   if (NConsoleClose::TestBreakSignal())
122     return E_ABORT;
123   #endif
124
125   if (final)
126   {
127     UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
128     PrintResults(f, info, rating, EncodeRes);
129   }
130   return S_OK;
131 }
132
133 static const char *kSep = "  | ";
134
135
136 HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
137 {
138   #ifdef BREAK_HANDLER
139   if (NConsoleClose::TestBreakSignal())
140     return E_ABORT;
141   #endif
142   if (final)
143   {
144     UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
145     fprintf(f, kSep);
146     CBenchInfo info2 = info;
147     info2.UnpackSize *= info2.NumIterations;
148     info2.PackSize *= info2.NumIterations;
149     info2.NumIterations = 1;
150     PrintResults(f, info2, rating, DecodeRes);
151   }
152   return S_OK;
153 }
154
155 static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
156 {
157   fprintf(f, "\nRAM %s ", sizeString);
158   PrintNumber(f, (size >> 20), 5);
159   fprintf(f, " MB,  # %s %3d", threadsString, (unsigned int)numThreads);
160 }
161
162 HRESULT LzmaBenchCon(
163   #ifdef EXTERNAL_LZMA
164   CCodecs *codecs,
165   #endif
166   FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
167 {
168   if (!CrcInternalTest())
169     return S_FALSE;
170   #ifdef BENCH_MT
171   UInt64 ramSize = NWindows::NSystem::GetRamSize();  // 
172   UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
173   PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
174   if (numThreads == (UInt32)-1)
175     numThreads = numCPUs;
176   if (numThreads > 1)
177     numThreads &= ~1;
178   if (dictionary == (UInt32)-1)
179   {
180     int dicSizeLog;
181     for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
182       if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
183         break;
184     dictionary = (1 << dicSizeLog);
185   }
186   #else
187   if (dictionary == (UInt32)-1)
188     dictionary = (1 << 22);
189   numThreads = 1;
190   #endif
191
192   PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads:   ", numThreads);
193
194   CBenchCallback callback;
195   callback.Init();
196   callback.f = f;
197   
198   fprintf(f, "\n\nDict        Compressing          |        Decompressing\n   ");
199   int j;
200   for (j = 0; j < 2; j++)
201   {
202     fprintf(f, "   Speed Usage    R/U Rating");
203     if (j == 0)
204       fprintf(f, kSep);
205   }
206   fprintf(f, "\n   ");
207   for (j = 0; j < 2; j++)
208   {
209     fprintf(f, "    KB/s     %%   MIPS   MIPS");
210     if (j == 0)
211       fprintf(f, kSep);
212   }
213   fprintf(f, "\n\n");
214   for (UInt32 i = 0; i < numIterations; i++)
215   {
216     const int kStartDicLog = 22;
217     int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
218     while (((UInt32)1 << pow) > dictionary)
219       pow--;
220     for (; ((UInt32)1 << pow) <= dictionary; pow++)
221     {
222       fprintf(f, "%2d:", pow);
223       callback.dictionarySize = (UInt32)1 << pow;
224       HRESULT res = LzmaBench(
225         #ifdef EXTERNAL_LZMA
226         codecs,
227         #endif
228         numThreads, callback.dictionarySize, &callback);
229       fprintf(f, "\n");
230       RINOK(res);
231     }
232   }
233   callback.Normalize();
234   fprintf(f, "----------------------------------------------------------------\nAvr:");
235   PrintTotals(f, callback.EncodeRes);
236   fprintf(f, "     ");
237   PrintTotals(f, callback.DecodeRes);
238   fprintf(f, "\nTot:");
239   CTotalBenchRes midRes;
240   midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
241   PrintTotals(f, midRes);
242   fprintf(f, "\n");
243   return S_OK;
244 }
245
246 struct CTempValues
247 {
248   UInt64 *Values;
249   CTempValues(UInt32 num) { Values = new UInt64[num]; }
250   ~CTempValues() { delete []Values; }
251 };
252
253 HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
254 {
255   if (!CrcInternalTest())
256     return S_FALSE;
257
258   #ifdef BENCH_MT
259   UInt64 ramSize = NWindows::NSystem::GetRamSize();
260   UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
261   PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
262   if (numThreads == (UInt32)-1)
263     numThreads = numCPUs;
264   #else
265   numThreads = 1;
266   #endif
267   if (dictionary == (UInt32)-1)
268     dictionary = (1 << 24);
269
270   CTempValues speedTotals(numThreads);
271   fprintf(f, "\n\nSize");
272   for (UInt32 ti = 0; ti < numThreads; ti++)
273   {
274     fprintf(f, " %5d", ti + 1);
275     speedTotals.Values[ti] = 0;
276   }
277   fprintf(f, "\n\n");
278
279   UInt64 numSteps = 0;
280   for (UInt32 i = 0; i < numIterations; i++)
281   {
282     for (int pow = 10; pow < 32; pow++)
283     {
284       UInt32 bufSize = (UInt32)1 << pow;
285       if (bufSize > dictionary)
286         break;
287       fprintf(f, "%2d: ", pow);
288       UInt64 speed;
289       for (UInt32 ti = 0; ti < numThreads; ti++)
290       {
291         #ifdef BREAK_HANDLER
292         if (NConsoleClose::TestBreakSignal())
293           return E_ABORT;
294         #endif
295         RINOK(CrcBench(ti + 1, bufSize, speed));
296         PrintNumber(f, (speed >> 20), 5);
297         speedTotals.Values[ti] += speed;
298       }
299       fprintf(f, "\n");
300       numSteps++;
301     }
302   }
303   if (numSteps != 0)
304   {
305     fprintf(f, "\nAvg:");
306     for (UInt32 ti = 0; ti < numThreads; ti++)
307       PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
308     fprintf(f, "\n");
309   }
310   return S_OK;
311 }