diff options
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/GUI/BenchmarkDialog.cpp')
-rw-r--r-- | installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/GUI/BenchmarkDialog.cpp | 581 |
1 files changed, 581 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/GUI/BenchmarkDialog.cpp new file mode 100644 index 000000000..c7a1cc5be --- /dev/null +++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/GUI/BenchmarkDialog.cpp @@ -0,0 +1,581 @@ +// BenchmarkDialog.cpp + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringToInt.h" +#include "Common/MyException.h" +#include "Windows/Thread.h" +#include "Windows/Error.h" +#include "Windows/System.h" +#include "../FileManager/HelpUtils.h" +// #include "BenchmarkDialogRes.h" +#include "BenchmarkDialog.h" + +using namespace NWindows; + +// const int kNumBenchDictionaryBitsStart = 21; + +static LPCWSTR kHelpTopic = L"fm/benchmark.htm"; + +static const UINT_PTR kTimerID = 4; +static const UINT kTimerElapse = 1000; + +#ifdef LANG +#include "../FileManager/LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_BENCHMARK_DICTIONARY, 0x02000D0C }, + { IDC_BENCHMARK_MEMORY, 0x03080001 }, + { IDC_BENCHMARK_NUM_THREADS, 0x02000D12 }, + { IDC_BENCHMARK_SPEED_LABEL, 0x03080004 }, + { IDC_BENCHMARK_RATING_LABEL, 0x03080005 }, + { IDC_BENCHMARK_COMPRESSING, 0x03080002 }, + { IDC_BENCHMARK_DECOMPRESSING, 0x03080003 }, + { IDC_BENCHMARK_CURRENT, 0x03080007 }, + { IDC_BENCHMARK_RESULTING, 0x03080008 }, + { IDC_BENCHMARK_CURRENT2, 0x03080007 }, + { IDC_BENCHMARK_RESULTING2, 0x03080008 }, + { IDC_BENCHMARK_TOTAL_RATING, 0x03080006 }, + { IDC_BENCHMARK_ELAPSED, 0x02000C01 }, + { IDC_BENCHMARK_SIZE, 0x02000C03 }, + { IDC_BENCHMARK_PASSES, 0x03080009 }, + // { IDC_BENCHMARK_ERRORS, 0x0308000A }, + { IDC_BENCHMARK_USAGE_LABEL, 0x0308000B }, + { IDC_BENCHMARK_RPU_LABEL, 0x0308000C }, + { IDC_BENCHMARK_COMBO_NUM_THREADS, 0x02000D12}, + + { IDC_BUTTON_STOP, 0x02000714 }, + { IDC_BUTTON_RESTART, 0x02000715 }, + { IDHELP, 0x02000720 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +static void MyMessageBoxError(HWND hwnd, LPCWSTR message) +{ + MessageBoxW(hwnd, message, L"7-Zip", MB_ICONERROR); +} + +const LPCTSTR kProcessingString = TEXT("..."); +const LPCTSTR kMB = TEXT(" MB"); +const LPCTSTR kMIPS = TEXT(" MIPS"); +const LPCTSTR kKBs = TEXT(" KB/s"); + +static const int kMinDicLogSize = 21; +static const UInt32 kMinDicSize = (1 << kMinDicLogSize); +static const UInt32 kMaxDicSize = + #ifdef _WIN64 + (1 << 30); + #else + (1 << 27); + #endif + +bool CBenchmarkDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x03080000); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + _syncInfo.Init(); + + m_Dictionary.Attach(GetItem(IDC_BENCHMARK_COMBO_DICTIONARY)); + int cur = 0; + // _syncInfo.DictionarySize = (1 << kNumBenchDictionaryBitsStart); + + UInt32 numCPUs = NSystem::GetNumberOfProcessors(); + if (numCPUs < 1) + numCPUs = 1; + numCPUs = MyMin(numCPUs, (UInt32)(1 << 8)); + cur = 0; + bool setDefaultThreads = (_syncInfo.NumThreads == (UInt32)(-1)); + if (setDefaultThreads) + { + _syncInfo.NumThreads = numCPUs; + if (_syncInfo.NumThreads > 1) + _syncInfo.NumThreads &= ~1; + } + + UInt64 ramSize = NSystem::GetRamSize(); + bool setDefaultDictionary = (_syncInfo.DictionarySize == (UInt32)(-1)); + if (setDefaultDictionary) + { + int dicSizeLog; + for (dicSizeLog = 25; dicSizeLog >= kBenchMinDicLogSize; dicSizeLog--) + if (GetBenchMemoryUsage(_syncInfo.NumThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize) + break; + _syncInfo.DictionarySize = (1 << dicSizeLog); + } + if (_syncInfo.DictionarySize < kMinDicSize) + _syncInfo.DictionarySize = kMinDicSize; + if (_syncInfo.DictionarySize > kMaxDicSize) + _syncInfo.DictionarySize = kMaxDicSize; + + for (int i = kMinDicLogSize; i <= 30; i++) + for (int j = 0; j < 2; j++) + { + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if (dictionary > kMaxDicSize) + continue; + TCHAR s[40]; + ConvertUInt64ToString((dictionary >> 20), s); + lstrcat(s, kMB); + int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, dictionary); + if (dictionary <= _syncInfo.DictionarySize) + cur = index; + } + m_Dictionary.SetCurSel(cur); + + m_NumThreads.Attach(GetItem(IDC_BENCHMARK_COMBO_NUM_THREADS)); + for (UInt32 num = 1; ;) + { + if (num > numCPUs * 2) + break; + TCHAR s[40]; + ConvertUInt64ToString(num, s); + int index = (int)m_NumThreads.AddString(s); + m_NumThreads.SetItemData(index, num); + if (num <= numCPUs && setDefaultThreads) + { + _syncInfo.NumThreads = num; + cur = index; + } + if (num > 1) + num++; + num++; + } + m_NumThreads.SetCurSel(cur); + + OnChangeSettings(); + + _syncInfo._startEvent.Set(); + _timer = SetTimer(kTimerID, kTimerElapse); + return CModalDialog::OnInit(); +} + +UInt32 CBenchmarkDialog::GetNumberOfThreads() +{ + return (UInt32)m_NumThreads.GetItemData(m_NumThreads.GetCurSel()); +} + +UInt32 CBenchmarkDialog::OnChangeDictionary() +{ + UInt32 dictionary = (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); + UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dictionary); + memUsage = (memUsage + (1 << 20) - 1) >> 20; + TCHAR s[40]; + ConvertUInt64ToString(memUsage, s); + lstrcat(s, kMB); + SetItemText(IDC_BENCHMARK_MEMORY_VALUE, s); + return dictionary; +} + +static const UInt32 g_IDs[] = +{ + IDC_BENCHMARK_COMPRESSING_USAGE, + IDC_BENCHMARK_COMPRESSING_USAGE2, + IDC_BENCHMARK_COMPRESSING_SPEED, + IDC_BENCHMARK_COMPRESSING_SPEED2, + IDC_BENCHMARK_COMPRESSING_RATING, + IDC_BENCHMARK_COMPRESSING_RATING2, + IDC_BENCHMARK_COMPRESSING_RPU, + IDC_BENCHMARK_COMPRESSING_RPU2, + + IDC_BENCHMARK_DECOMPRESSING_SPEED, + IDC_BENCHMARK_DECOMPRESSING_SPEED2, + IDC_BENCHMARK_DECOMPRESSING_RATING, + IDC_BENCHMARK_DECOMPRESSING_RATING2, + IDC_BENCHMARK_DECOMPRESSING_USAGE, + IDC_BENCHMARK_DECOMPRESSING_USAGE2, + IDC_BENCHMARK_DECOMPRESSING_RPU, + IDC_BENCHMARK_DECOMPRESSING_RPU2, + + IDC_BENCHMARK_TOTAL_USAGE_VALUE, + IDC_BENCHMARK_TOTAL_RATING_VALUE, + IDC_BENCHMARK_TOTAL_RPU_VALUE +}; + +void CBenchmarkDialog::OnChangeSettings() +{ + EnableItem(IDC_BUTTON_STOP, true); + UInt32 dictionary = OnChangeDictionary(); + TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 }; + ConvertUInt64ToString(NSystem::GetNumberOfProcessors(), s + 2); + SetItemText(IDC_BENCHMARK_HARDWARE_THREADS, s); + for (int i = 0; i < sizeof(g_IDs) / sizeof(g_IDs[0]); i++) + SetItemText(g_IDs[i], kProcessingString); + _startTime = GetTickCount(); + PrintTime(); + NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS); + _syncInfo.Init(); + _syncInfo.DictionarySize = dictionary; + _syncInfo.Changed = true; + _syncInfo.NumThreads = GetNumberOfThreads(); +} + +void CBenchmarkDialog::OnRestartButton() +{ + OnChangeSettings(); +} + +void CBenchmarkDialog::OnStopButton() +{ + EnableItem(IDC_BUTTON_STOP, false); + _syncInfo.Pause(); +} + +void CBenchmarkDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +void CBenchmarkDialog::OnCancel() +{ + _syncInfo.Stop(); + KillTimer(_timer); + CModalDialog::OnCancel(); +} + +static void GetTimeString(UInt64 timeValue, TCHAR *s) +{ + wsprintf(s, TEXT("%02d:%02d:%02d"), + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); +} + +void CBenchmarkDialog::PrintTime() +{ + UInt32 curTime = ::GetTickCount(); + UInt32 elapsedTime = (curTime - _startTime); + UInt32 elapsedSec = elapsedTime / 1000; + if (elapsedSec != 0 && _syncInfo.WasPaused()) + return; + TCHAR s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDC_BENCHMARK_ELAPSED_VALUE, s); +} + +void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) +{ + TCHAR s[40]; + ConvertUInt64ToString(rating / 1000000, s); + lstrcat(s, kMIPS); + SetItemText(controlID, s); +} + +void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID) +{ + TCHAR s[40]; + ConvertUInt64ToString((usage + 5000) / 10000, s); + lstrcat(s, TEXT("%")); + SetItemText(controlID, s); +} + +void CBenchmarkDialog::PrintResults( + UInt32 dictionarySize, + const CBenchInfo2 &info, + UINT usageID, UINT speedID, UINT rpuID, UINT ratingID, + bool decompressMode) +{ + if (info.GlobalTime == 0) + return; + + UInt64 size = info.UnpackSize; + TCHAR s[40]; + { + UInt64 speed = size * info.GlobalFreq / info.GlobalTime; + ConvertUInt64ToString(speed / 1024, s); + lstrcat(s, kKBs); + SetItemText(speedID, s); + } + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, size, info.PackSize, 1); + else + rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, size * info.NumIterations); + + PrintRating(rating, ratingID); + PrintRating(GetRatingPerUsage(info, rating), rpuID); + PrintUsage(GetUsage(info), usageID); +} + +bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + PrintTime(); + NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS); + + TCHAR s[40]; + ConvertUInt64ToString((_syncInfo.ProcessedSize >> 20), s); + lstrcat(s, kMB); + SetItemText(IDC_BENCHMARK_SIZE_VALUE, s); + + ConvertUInt64ToString(_syncInfo.NumPasses, s); + SetItemText(IDC_BENCHMARK_PASSES_VALUE, s); + + /* + ConvertUInt64ToString(_syncInfo.NumErrors, s); + SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s); + */ + + { + UInt32 dicSizeTemp = (UInt32)MyMax(_syncInfo.ProcessedSize, UInt64(1) << 20); + dicSizeTemp = MyMin(dicSizeTemp, _syncInfo.DictionarySize), + PrintResults(dicSizeTemp, + _syncInfo.CompressingInfoTemp, + IDC_BENCHMARK_COMPRESSING_USAGE, + IDC_BENCHMARK_COMPRESSING_SPEED, + IDC_BENCHMARK_COMPRESSING_RPU, + IDC_BENCHMARK_COMPRESSING_RATING); + } + + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.CompressingInfo, + IDC_BENCHMARK_COMPRESSING_USAGE2, + IDC_BENCHMARK_COMPRESSING_SPEED2, + IDC_BENCHMARK_COMPRESSING_RPU2, + IDC_BENCHMARK_COMPRESSING_RATING2); + } + + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.DecompressingInfoTemp, + IDC_BENCHMARK_DECOMPRESSING_USAGE, + IDC_BENCHMARK_DECOMPRESSING_SPEED, + IDC_BENCHMARK_DECOMPRESSING_RPU, + IDC_BENCHMARK_DECOMPRESSING_RATING, + true); + } + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.DecompressingInfo, + IDC_BENCHMARK_DECOMPRESSING_USAGE2, + IDC_BENCHMARK_DECOMPRESSING_SPEED2, + IDC_BENCHMARK_DECOMPRESSING_RPU2, + IDC_BENCHMARK_DECOMPRESSING_RATING2, + true); + if (_syncInfo.DecompressingInfo.GlobalTime > 0 && + _syncInfo.CompressingInfo.GlobalTime > 0) + { + UInt64 comprRating = GetCompressRating(_syncInfo.DictionarySize, + _syncInfo.CompressingInfo.GlobalTime, _syncInfo.CompressingInfo.GlobalFreq, _syncInfo.CompressingInfo.UnpackSize); + UInt64 decomprRating = GetDecompressRating(_syncInfo.DecompressingInfo.GlobalTime, + _syncInfo.DecompressingInfo.GlobalFreq, _syncInfo.DecompressingInfo.UnpackSize, + _syncInfo.DecompressingInfo.PackSize, 1); + PrintRating((comprRating + decomprRating) / 2, IDC_BENCHMARK_TOTAL_RATING_VALUE); + PrintRating(( + GetRatingPerUsage(_syncInfo.CompressingInfo, comprRating) + + GetRatingPerUsage(_syncInfo.DecompressingInfo, decomprRating)) / 2, IDC_BENCHMARK_TOTAL_RPU_VALUE); + PrintUsage((GetUsage(_syncInfo.CompressingInfo) + GetUsage(_syncInfo.DecompressingInfo)) / 2, IDC_BENCHMARK_TOTAL_USAGE_VALUE); + } + } + return true; +} + +bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE && + (itemID == IDC_BENCHMARK_COMBO_DICTIONARY || + itemID == IDC_BENCHMARK_COMBO_NUM_THREADS)) + { + OnChangeSettings(); + return true; + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + +bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_BUTTON_RESTART: + OnRestartButton(); + return true; + case IDC_BUTTON_STOP: + OnStopButton(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +struct CThreadBenchmark +{ + CProgressSyncInfo *SyncInfo; + UInt64 _startTime; + #ifdef EXTERNAL_LZMA + CCodecs *codecs; + #endif + // UInt32 dictionarySize; + // UInt32 numThreads; + + HRESULT Process(); + HRESULT Result; + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process(); + return 0; + } +}; + +struct CBenchCallback: public IBenchCallback +{ + UInt32 dictionarySize; + CProgressSyncInfo *SyncInfo; + HRESULT SetEncodeResult(const CBenchInfo &info, bool final); + HRESULT SetDecodeResult(const CBenchInfo &info, bool final); +}; + +HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final) +{ + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Changed || SyncInfo->Paused || SyncInfo->Stopped) + return E_ABORT; + SyncInfo->ProcessedSize = info.UnpackSize; + if (final && SyncInfo->CompressingInfo.GlobalTime == 0) + { + (CBenchInfo&)SyncInfo->CompressingInfo = info; + if (SyncInfo->CompressingInfo.GlobalTime == 0) + SyncInfo->CompressingInfo.GlobalTime = 1; + } + else + (CBenchInfo&)SyncInfo->CompressingInfoTemp = info; + + return S_OK; +} + +HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final) +{ + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Changed || SyncInfo->Paused || SyncInfo->Stopped) + return E_ABORT; + CBenchInfo info2 = info; + if (info2.NumIterations == 0) + info2.NumIterations = 1; + + info2.UnpackSize *= info2.NumIterations; + info2.PackSize *= info2.NumIterations; + info2.NumIterations = 1; + + if (final && SyncInfo->DecompressingInfo.GlobalTime == 0) + { + (CBenchInfo&)SyncInfo->DecompressingInfo = info2; + if (SyncInfo->DecompressingInfo.GlobalTime == 0) + SyncInfo->DecompressingInfo.GlobalTime = 1; + } + else + (CBenchInfo&)SyncInfo->DecompressingInfoTemp = info2; + return S_OK; +} + +HRESULT CThreadBenchmark::Process() +{ + try + { + SyncInfo->WaitCreating(); + for (;;) + { + if (SyncInfo->WasStopped()) + return 0; + if (SyncInfo->WasPaused()) + { + Sleep(200); + continue; + } + UInt32 dictionarySize; + UInt32 numThreads; + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Stopped || SyncInfo->Paused) + continue; + if (SyncInfo->Changed) + SyncInfo->Init(); + dictionarySize = SyncInfo->DictionarySize; + numThreads = SyncInfo->NumThreads; + } + + CBenchCallback callback; + callback.dictionarySize = dictionarySize; + callback.SyncInfo = SyncInfo; + HRESULT result; + try + { + result = LzmaBench( + #ifdef EXTERNAL_LZMA + codecs, + #endif + numThreads, dictionarySize, &callback); + } + catch(...) + { + result = E_FAIL; + } + + if (result != S_OK) + { + if (result != E_ABORT) + { + // SyncInfo->NumErrors++; + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + SyncInfo->Pause(); + } + CSysString message; + if (result == S_FALSE) + message = TEXT("Decoding error"); + else + message = NError::MyFormatMessage(result); + MessageBox(0, message, TEXT("7-Zip"), MB_ICONERROR); + } + } + else + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + SyncInfo->NumPasses++; + } + } + // return S_OK; + } + catch(CSystemException &e) + { + MessageBox(0, NError::MyFormatMessage(e.ErrorCode), TEXT("7-Zip"), MB_ICONERROR); + return E_FAIL; + } + catch(...) + { + MyMessageBoxError(0, L"Some error"); + return E_FAIL; + } +} + +HRESULT Benchmark( + #ifdef EXTERNAL_LZMA + CCodecs *codecs, + #endif + UInt32 numThreads, UInt32 dictionarySize) +{ + CThreadBenchmark benchmarker; + #ifdef EXTERNAL_LZMA + benchmarker.codecs = codecs; + #endif + + CBenchmarkDialog benchmarkDialog; + benchmarkDialog._syncInfo.DictionarySize = dictionarySize; + benchmarkDialog._syncInfo.NumThreads = numThreads; + + benchmarker.SyncInfo = &benchmarkDialog._syncInfo; + NWindows::CThread thread; + RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker)); + benchmarkDialog.Create(0); + return thread.Wait(); +} |