diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2021-11-29 06:01:13 +0300 |
---|---|---|
committer | fn ⌃ ⌥ <70830482+FnControlOption@users.noreply.github.com> | 2021-11-29 06:01:13 +0300 |
commit | d789d4137d8a7c16696c5bc1b13f24bb887eb7ea (patch) | |
tree | 6a7e0bf0e9b292d92dc91c6ef68a579fe2adcbe7 /CPP/7zip | |
parent | 585698650f7257d2cefa6a3a2a49d5bbe84fd9b2 (diff) |
21.0321.03
Diffstat (limited to 'CPP/7zip')
52 files changed, 2729 insertions, 1018 deletions
diff --git a/CPP/7zip/7zip_gcc.mak b/CPP/7zip/7zip_gcc.mak index 122686ff..59074214 100644 --- a/CPP/7zip/7zip_gcc.mak +++ b/CPP/7zip/7zip_gcc.mak @@ -2,7 +2,7 @@ # USE_ASM = 1 # IS_X64 = 1 # MY_ARCH = - +# USE_ASM= MY_ARCH_2 = $(MY_ARCH) @@ -23,6 +23,8 @@ CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ -fPIC +# -D_7ZIP_AFFINITY_DISABLE + ifdef SystemDrive IS_MINGW = 1 @@ -186,6 +188,8 @@ $O/Lang.o: ../../../Common/Lang.cpp $(CXX) $(CXXFLAGS) $< $O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp $(CXX) $(CXXFLAGS) $< +$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp + $(CXX) $(CXXFLAGS) $< $O/MyMap.o: ../../../Common/MyMap.cpp $(CXX) $(CXXFLAGS) $< $O/MyString.o: ../../../Common/MyString.cpp @@ -1095,6 +1099,7 @@ $O/XzCrc64.o: ../../../../C/XzCrc64.c ifdef USE_ASM ifdef IS_X64 USE_X86_ASM=1 +USE_X64_ASM=1 else ifdef IS_X86 USE_X86_ASM=1 @@ -1126,6 +1131,13 @@ $O/AesOpt.o: ../../../../C/AesOpt.c $(CC) $(CFLAGS) $< endif +ifdef USE_X64_ASM +$O/LzFindOpt.o: ../../../../Asm/x86/LzFindOpt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/LzFindOpt.o: ../../../../C/LzFindOpt.c + $(CC) $(CFLAGS) $< +endif ifdef USE_LZMA_DEC_ASM diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index b549d94a..8bb87341 100644 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -133,7 +133,7 @@ HRESULT CHandler::SetMainMethod( if (_numSolidBytesDefined) continue; - UInt32 dicSize; + UInt64 dicSize; switch (methodFull.Id) { case k_LZMA: diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index c5c7166e..c47659ac 100644 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -89,6 +89,7 @@ namespace NFileHeader kZip64 = 0x01, kNTFS = 0x0A, kStrongEncrypt = 0x17, + kIzNtSecurityDescriptor = 0x4453, kUnixTime = 0x5455, kUnixExtra = 0x5855, kIzUnicodeComment = 0x6375, diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index 38921dce..be336485 100644 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -37,6 +37,7 @@ static const CUInt32PCharPair g_ExtraTypes[] = { NExtraID::kUnix3Extra, "ux" }, { NExtraID::kIzUnicodeComment, "uc" }, { NExtraID::kIzUnicodeName, "up" }, + { NExtraID::kIzNtSecurityDescriptor, "SD" }, { NExtraID::kWzAES, "WzAES" }, { NExtraID::kApkAlign, "ApkAlign" } }; diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp index 145cf2ca..7a1f79df 100644 --- a/CPP/7zip/Bundles/Alone/Alone.dsp +++ b/CPP/7zip/Bundles/Alone/Alone.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -270,6 +270,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -306,6 +310,18 @@ SOURCE=..\..\..\Common\ListFileUtils.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File @@ -322,6 +338,10 @@ SOURCE=..\..\..\Common\MyInitGuid.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -330,6 +350,10 @@ SOURCE=..\..\..\Common\MyString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyUnknown.h # End Source File # Begin Source File @@ -342,6 +366,10 @@ SOURCE=..\..\..\Common\MyVector.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -478,6 +506,10 @@ SOURCE=..\..\..\Windows\FileLink.cpp # End Source File # Begin Source File +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\FileName.cpp # End Source File # Begin Source File @@ -506,6 +538,10 @@ SOURCE=..\..\..\Windows\MemoryLock.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -538,6 +574,10 @@ SOURCE=..\..\..\Windows\Registry.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Synchronization.cpp # End Source File # Begin Source File @@ -654,6 +694,10 @@ SOURCE=..\..\Common\MemBlocks.cpp # End Source File # Begin Source File +SOURCE=..\..\Common\MemBlocks.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\MethodId.cpp # End Source File # Begin Source File @@ -769,6 +813,10 @@ SOURCE=..\..\Common\VirtThread.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\Compress\BZip2Const.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BZip2Crc.cpp # End Source File # Begin Source File @@ -909,10 +957,6 @@ SOURCE=..\..\Compress\DeflateEncoder.h # End Source File # Begin Source File -SOURCE=..\..\Compress\DeflateExtConst.h -# End Source File -# Begin Source File - SOURCE=..\..\Compress\DeflateRegister.cpp # End Source File # End Group @@ -1678,6 +1722,10 @@ SOURCE=..\..\UI\Common\DefaultName.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\DirItem.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\EnumDirItems.cpp # End Source File # Begin Source File @@ -1686,6 +1734,10 @@ SOURCE=..\..\UI\Common\EnumDirItems.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\Extract.cpp # End Source File # Begin Source File @@ -1702,6 +1754,10 @@ SOURCE=..\..\UI\Common\ExtractingFilePath.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\HashCalc.cpp # End Source File # Begin Source File @@ -1710,6 +1766,10 @@ SOURCE=..\..\UI\Common\HashCalc.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\LoadCodecs.cpp # End Source File # Begin Source File @@ -1726,6 +1786,10 @@ SOURCE=..\..\UI\Common\OpenArchive.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\Property.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\PropIDUtils.cpp # End Source File # Begin Source File @@ -1912,6 +1976,10 @@ SOURCE=..\..\Crypto\RandGen.h # End Source File # Begin Source File +SOURCE=..\..\Crypto\Sha1Cls.h +# End Source File +# Begin Source File + SOURCE=..\..\Crypto\WzAes.cpp # End Source File # Begin Source File @@ -1959,6 +2027,10 @@ SOURCE=..\..\ICoder.h # End Source File # Begin Source File +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + SOURCE=..\..\IMyUnknown.h # End Source File # Begin Source File @@ -1975,6 +2047,10 @@ SOURCE=..\..\IStream.h # End Source File # Begin Source File +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + SOURCE=..\..\PropID.h # End Source File # End Group @@ -2223,6 +2299,10 @@ SOURCE=..\..\..\..\C\7zTypes.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -2440,6 +2520,10 @@ SOURCE=..\..\..\..\C\BwtSort.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -2593,6 +2677,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzHash.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile index 0fce341b..ca3392db 100644 --- a/CPP/7zip/Bundles/Alone/makefile +++ b/CPP/7zip/Bundles/Alone/makefile @@ -1,6 +1,7 @@ PROG = 7za.exe # USE_C_AES = 1 # USE_C_SHA = 1 +# USE_C_LZFINDOPT = 1 COMMON_OBJS = \ $O\CommandLineParser.obj \ @@ -8,6 +9,7 @@ COMMON_OBJS = \ $O\CrcReg.obj \ $O\IntToString.obj \ $O\ListFileUtils.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\StdInStream.obj \ $O\StdOutStream.obj \ @@ -217,6 +219,7 @@ C_OBJS = \ !include "../../Aes.mak" !include "../../Crc.mak" !include "../../Crc64.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha1.mak" !include "../../Sha256.mak" diff --git a/CPP/7zip/Bundles/Alone/makefile.gcc b/CPP/7zip/Bundles/Alone/makefile.gcc index e63fc332..182e9a7c 100644 --- a/CPP/7zip/Bundles/Alone/makefile.gcc +++ b/CPP/7zip/Bundles/Alone/makefile.gcc @@ -110,6 +110,7 @@ COMMON_OBJS = \ $O/CrcReg.o \ $O/IntToString.o \ $O/ListFileUtils.o \ + $O/LzFindPrepare.o \ $O/MyString.o \ $O/NewHandler.o \ $O/StdInStream.o \ @@ -283,6 +284,7 @@ C_OBJS = \ $O/Delta.o \ $O/HuffEnc.o \ $O/LzFind.o \ + $O/LzFindOpt.o \ $O/Lzma2Dec.o \ $O/Lzma2DecMt.o \ $O/Lzma2Enc.o \ diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp index a46526bf..a15a5bfa 100644 --- a/CPP/7zip/Bundles/Alone7z/Alone.dsp +++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -306,6 +306,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File @@ -1681,6 +1685,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile index 803277ab..0a68e141 100644 --- a/CPP/7zip/Bundles/Alone7z/makefile +++ b/CPP/7zip/Bundles/Alone7z/makefile @@ -10,6 +10,7 @@ COMMON_OBJS = \ $O\CrcReg.obj \ $O\IntToString.obj \ $O\ListFileUtils.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\StdInStream.obj \ $O\StdOutStream.obj \ @@ -152,6 +153,7 @@ C_OBJS = \ !include "../../Aes.mak" !include "../../Crc.mak" !include "../../Crc64.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha256.mak" diff --git a/CPP/7zip/Bundles/Alone7z/makefile.gcc b/CPP/7zip/Bundles/Alone7z/makefile.gcc index b1f69734..c1d6ac50 100644 --- a/CPP/7zip/Bundles/Alone7z/makefile.gcc +++ b/CPP/7zip/Bundles/Alone7z/makefile.gcc @@ -27,6 +27,7 @@ else MT_OBJS = \ $O/LzFindMt.o \ + $O/LzFindOpt.o \ $O/StreamBinder.o \ $O/Synchronization.o \ $O/VirtThread.o \ @@ -110,6 +111,7 @@ COMMON_OBJS = \ $O/CrcReg.o \ $O/IntToString.o \ $O/ListFileUtils.o \ + $O/LzFindPrepare.o \ $O/MyString.o \ $O/MyVector.o \ $O/NewHandler.o \ diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp index cccf1be5..86d788f0 100644 --- a/CPP/7zip/Bundles/Fm/FM.dsp +++ b/CPP/7zip/Bundles/Fm/FM.dsp @@ -1016,6 +1016,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Lzma2Dec.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -1514,6 +1519,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyBuffer.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile index ca66599a..7276f175 100644 --- a/CPP/7zip/Bundles/Format7z/makefile +++ b/CPP/7zip/Bundles/Format7z/makefile @@ -8,6 +8,7 @@ COMMON_OBJS = \ $O\CRC.obj \ $O\CrcReg.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\MyString.obj \ $O\Sha256Reg.obj \ @@ -137,6 +138,7 @@ C_OBJS = \ !include "../../Aes.mak" !include "../../Crc.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha256.mak" diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak index fedce5e0..53a8895a 100644 --- a/CPP/7zip/Bundles/Format7zF/Arc.mak +++ b/CPP/7zip/Bundles/Format7zF/Arc.mak @@ -3,6 +3,7 @@ COMMON_OBJS = \ $O\CrcReg.obj \ $O\DynLimBuf.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\MyMap.obj \ $O\MyString.obj \ $O\MyVector.obj \ @@ -287,6 +288,7 @@ C_OBJS = \ !include "../../Aes.mak" !include "../../Crc.mak" !include "../../Crc64.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../Sha1.mak" !include "../../Sha256.mak" diff --git a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak index c3dbf349..73711d3a 100644 --- a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak +++ b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak @@ -18,6 +18,7 @@ else MT_OBJS = \ $O/LzFindMt.o \ + $O/LzFindOpt.o \ $O/StreamBinder.o \ $O/Synchronization.o \ $O/VirtThread.o \ @@ -35,6 +36,7 @@ COMMON_OBJS = \ $O/CrcReg.o \ $O/DynLimBuf.o \ $O/IntToString.o \ + $O/LzFindPrepare.o \ $O/MyMap.o \ $O/MyString.o \ $O/MyVector.o \ diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp index 67883ebc..36ac6042 100644 --- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp +++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp @@ -267,6 +267,10 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyBuffer.h # End Source File # Begin Source File @@ -1869,6 +1873,22 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzHash.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile index 5c05abd1..c2237152 100644 --- a/CPP/7zip/Bundles/Format7zR/makefile +++ b/CPP/7zip/Bundles/Format7zR/makefile @@ -7,6 +7,7 @@ COMMON_OBJS = \ $O\CRC.obj \ $O\CrcReg.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\MyString.obj \ $O\StringConvert.obj \ @@ -111,6 +112,7 @@ C_OBJS = \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp index 907b23e0..d7326efc 100644 --- a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp +++ b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp @@ -212,6 +212,10 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File @@ -316,6 +320,14 @@ SOURCE=..\..\Common\MethodProps.h # End Source File # Begin Source File +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\StreamUtils.cpp # End Source File # Begin Source File @@ -441,6 +453,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzHash.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile index e87becc4..5e53327a 100644 --- a/CPP/7zip/Bundles/LzmaCon/makefile +++ b/CPP/7zip/Bundles/LzmaCon/makefile @@ -14,6 +14,7 @@ COMMON_OBJS = \ $O\CRC.obj \ $O\CrcReg.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\MyString.obj \ $O\MyVector.obj \ $O\NewHandler.obj \ @@ -33,6 +34,7 @@ WIN_OBJS = \ $O\FileStreams.obj \ $O\FilterCoder.obj \ $O\MethodProps.obj \ + $O\StreamObjects.obj \ $O\StreamUtils.obj \ UI_COMMON_OBJS = \ @@ -55,6 +57,7 @@ C_OBJS = \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzFindOpt.mak" !include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/CPP/7zip/Bundles/LzmaCon/makefile.gcc index f9ccfce4..58c204af 100644 --- a/CPP/7zip/Bundles/LzmaCon/makefile.gcc +++ b/CPP/7zip/Bundles/LzmaCon/makefile.gcc @@ -18,6 +18,7 @@ else MT_OBJS = \ $O/LzFindMt.o \ + $O/LzFindOpt.o \ $O/Synchronization.o \ $O/Threads.o \ @@ -55,6 +56,7 @@ COMMON_OBJS = \ $O/CRC.o \ $O/CrcReg.o \ $O/IntToString.o \ + $O/LzFindPrepare.o \ $O/MyString.o \ $O/MyVector.o \ $O/NewHandler.o \ @@ -83,6 +85,7 @@ CONSOLE_OBJS = \ $O/FileStreams.o \ $O/FilterCoder.o \ $O/MethodProps.o \ + $O/StreamObjects.o \ $O/StreamUtils.o \ C_OBJS = \ diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp index f351abbd..9b0652c6 100644 --- a/CPP/7zip/Common/MemBlocks.cpp +++ b/CPP/7zip/Common/MemBlocks.cpp @@ -67,7 +67,6 @@ HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) return E_OUTOFMEMORY; if (!CMemBlockManager::AllocateSpace_bool(numBlocks)) return E_OUTOFMEMORY; - Semaphore.Close(); // we need (maxCount = 1), if we want to create non-use empty Semaphore if (maxCount == 0) maxCount = 1; @@ -75,12 +74,13 @@ HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) // printf("\n Synchro.Create() \n"); WRes wres; #ifndef _WIN32 + Semaphore.Close(); wres = Synchro.Create(); if (wres != 0) return HRESULT_FROM_WIN32(wres); wres = Semaphore.Create(&Synchro, (UInt32)numLockBlocks, maxCount); #else - wres = Semaphore.Create((UInt32)numLockBlocks, maxCount); + wres = Semaphore.OptCreateInit((UInt32)numLockBlocks, maxCount); #endif return HRESULT_FROM_WIN32(wres); diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp index bea51db3..3ab89ddb 100644 --- a/CPP/7zip/Common/MethodProps.cpp +++ b/CPP/7zip/Common/MethodProps.cpp @@ -99,41 +99,65 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default } +static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp) +{ + if (number >= 64) + return E_INVALIDARG; + UInt32 val32; + if (number < 32) + val32 = (UInt32)1 << (unsigned)number; + /* + else if (number == 32 && reduce_4GB_to_32bits) + val32 = (UInt32)(Int32)-1; + */ + else + { + destProp = (UInt64)((UInt64)1 << (unsigned)number); + return S_OK; + } + destProp = (UInt32)val32; + return S_OK; +} + + static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) { + /* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1). + to fit the value to UInt32 for clients that do not support 64-bit values */ + const wchar_t *end; - UInt32 number = ConvertStringToUInt32(s, &end); - unsigned numDigits = (unsigned)(end - s.Ptr()); + const UInt64 number = ConvertStringToUInt64(s, &end); + const unsigned numDigits = (unsigned)(end - s.Ptr()); if (numDigits == 0 || s.Len() > numDigits + 1) return E_INVALIDARG; if (s.Len() == numDigits) - { - if (number >= 64) - return E_INVALIDARG; - if (number < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)number); - else - destProp = (UInt64)((UInt64)1 << (unsigned)number); - return S_OK; - } + return SetLogSizeProp(number, destProp); unsigned numBits; switch (MyCharLower_Ascii(s[numDigits])) { - case 'b': destProp = number; return S_OK; + case 'b': numBits = 0; break; case 'k': numBits = 10; break; case 'm': numBits = 20; break; case 'g': numBits = 30; break; default: return E_INVALIDARG; } - if (number < ((UInt32)1 << (32 - numBits))) - destProp = (UInt32)(number << numBits); + const UInt64 range4g = ((UInt64)1 << (32 - numBits)); + if (number < range4g) + destProp = (UInt32)((UInt32)number << numBits); + /* + else if (number == range4g && reduce_4GB_to_32bits) + destProp = (UInt32)(Int32)-1; + */ + else if (numBits == 0) + destProp = (UInt64)number; + else if (number >= ((UInt64)1 << (64 - numBits))) + return E_INVALIDARG; else destProp = (UInt64)((UInt64)number << numBits); - return S_OK; } @@ -141,16 +165,8 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) { if (prop.vt == VT_UI4) - { - UInt32 v = prop.ulVal; - if (v >= 64) - return E_INVALIDARG; - if (v < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)v); - else - destProp = (UInt64)((UInt64)1 << (unsigned)v); - return S_OK; - } + return SetLogSizeProp(prop.ulVal, destProp); + if (prop.vt == VT_BSTR) { UString s; diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h index e0519b16..bd9283f0 100644 --- a/CPP/7zip/Common/MethodProps.h +++ b/CPP/7zip/Common/MethodProps.h @@ -64,23 +64,34 @@ public: unsigned GetLevel() const; int Get_NumThreads() const { - int i = FindProp(NCoderPropID::kNumThreads); + const int i = FindProp(NCoderPropID::kNumThreads); if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) - return (int)Props[(unsigned)i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return (int)val.ulVal; + } return -1; } - bool Get_DicSize(UInt32 &res) const + bool Get_DicSize(UInt64 &res) const { res = 0; - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { - res = Props[(unsigned)i].Value.ulVal; + res = val.ulVal; return true; } + if (val.vt == VT_UI8) + { + res = val.uhVal.QuadPart; + return true; + } + } return false; } @@ -90,23 +101,26 @@ public: { int i = FindProp(NCoderPropID::kAlgorithm); if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) - return Props[(unsigned)i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + } return GetLevel() >= 5 ? 1 : 0; } - UInt32 Get_Lzma_DicSize() const + UInt64 Get_Lzma_DicSize() const { - int i = FindProp(NCoderPropID::kDictionarySize); - if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) - return Props[(unsigned)i].Value.ulVal; - unsigned level = GetLevel(); - return - ( level <= 3 ? (1 << (level * 2 + 16)) : - ( level <= 6 ? (1 << (level + 19)) : - ( level <= 7 ? (1 << 25) : (1 << 26) + UInt64 v; + if (Get_DicSize(v)) + return v; + const unsigned level = GetLevel(); + const UInt32 dictSize = + ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : + ( level <= 6 ? ((UInt32)1 << (level + 19)) : + ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) ))); + return dictSize; } bool Get_Lzma_Eos() const @@ -152,7 +166,7 @@ public: UInt64 GetProp_BlockSize(PROPID id) const { - int i = FindProp(id); + const int i = FindProp(id); if (i >= 0) { const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; @@ -176,7 +190,7 @@ public: } const UInt32 kMinSize = (UInt32)1 << 20; const UInt32 kMaxSize = (UInt32)1 << 28; - UInt32 dictSize = Get_Lzma_DicSize(); + const UInt64 dictSize = Get_Lzma_DicSize(); UInt64 blockSize = (UInt64)dictSize << 2; if (blockSize < kMinSize) blockSize = kMinSize; if (blockSize > kMaxSize) blockSize = kMaxSize; @@ -204,29 +218,38 @@ public: UInt32 Get_BZip2_BlockSize() const { - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { - UInt32 blockSize = Props[(unsigned)i].Value.ulVal; + UInt32 blockSize = val.ulVal; const UInt32 kDicSizeMin = 100000; const UInt32 kDicSizeMax = 900000; if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; return blockSize; } - unsigned level = GetLevel(); + } + const unsigned level = GetLevel(); return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); } - UInt32 Get_Ppmd_MemSize() const + UInt64 Get_Ppmd_MemSize() const { - int i = FindProp(NCoderPropID::kUsedMemorySize); + const int i = FindProp(NCoderPropID::kUsedMemorySize); if (i >= 0) - if (Props[(unsigned)i].Value.vt == VT_UI4) - return Props[(unsigned)i].Value.ulVal; - unsigned level = GetLevel(); - return ((UInt32)1 << (level + 19)); + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + if (val.vt == VT_UI8) + return val.uhVal.QuadPart; + } + const unsigned level = GetLevel(); + const UInt32 mem = (UInt32)1 << (level + 19); + return mem; } void AddProp_Level(UInt32 level) diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp index b3e710f9..b16124c2 100644 --- a/CPP/7zip/Common/OffsetStream.cpp +++ b/CPP/7zip/Common/OffsetStream.cpp @@ -20,13 +20,13 @@ STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *proc STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { - UInt64 absoluteNewPosition; if (seekOrigin == STREAM_SEEK_SET) { if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; offset += _offset; } + UInt64 absoluteNewPosition = 0; // =0 for gcc-10 HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); if (newPosition) *newPosition = absoluteNewPosition - _offset; diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp index fbf2a0de..6b6e0e58 100644 --- a/CPP/7zip/Common/StreamBinder.cpp +++ b/CPP/7zip/Common/StreamBinder.cpp @@ -52,9 +52,9 @@ HRESULT CStreamBinder::Create_ReInit() RINOK(Event__Create_or_Reset(_canRead_Event)); // RINOK(Event__Create_or_Reset(_canWrite_Event)); - _canWrite_Semaphore.Close(); + // _canWrite_Semaphore.Close(); // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() - _canWrite_Semaphore.Create(0, 3); + _canWrite_Semaphore.OptCreateInit(0, 3); // _readingWasClosed = false; _readingWasClosed2 = false; diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp index e34c2c0c..0206ce8d 100644 --- a/CPP/7zip/Compress/DeflateDecoder.cpp +++ b/CPP/7zip/Compress/DeflateDecoder.cpp @@ -274,15 +274,24 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputPro sym = m_DistDecoder.Decode(&m_InBitStream); if (sym >= _numDistLevels) return S_FALSE; - UInt32 distance = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); - if (!m_OutWindowStream.CopyBlock(distance, locLen)) + sym = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); + /* + if (sym >= 4) + { + // sym &= 31; + const unsigned numDirectBits = (unsigned)(((sym >> 1) - 1)); + sym = (2 | (sym & 1)) << numDirectBits; + sym += m_InBitStream.ReadBits(numDirectBits); + } + */ + if (!m_OutWindowStream.CopyBlock(sym, locLen)) return S_FALSE; curSize -= locLen; len -= locLen; if (len != 0) { _remainLen = (Int32)len; - _rep0 = distance; + _rep0 = sym; break; } } diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp index fb24c6b0..8168ec78 100644 --- a/CPP/7zip/Compress/DeflateEncoder.cpp +++ b/CPP/7zip/Compress/DeflateEncoder.cpp @@ -44,7 +44,9 @@ static const Byte kNoLenStatPrice = 11; static const Byte kNoPosStatPrice = 6; static Byte g_LenSlots[kNumLenSymbolsMax]; -static Byte g_FastPos[1 << 9]; + +#define kNumLogBits 9 // do not change it +static Byte g_FastPos[1 << kNumLogBits]; class CFastPosInit { @@ -60,7 +62,7 @@ public: g_LenSlots[c] = (Byte)i; } - const unsigned kFastSlots = 18; + const unsigned kFastSlots = kNumLogBits * 2; unsigned c = 0; for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) { @@ -73,14 +75,24 @@ public: static CFastPosInit g_FastPosInit; - inline UInt32 GetPosSlot(UInt32 pos) { + /* if (pos < 0x200) return g_FastPos[pos]; return g_FastPos[pos >> 8] + 16; + */ + // const unsigned zz = (pos < ((UInt32)1 << (kNumLogBits))) ? 0 : 8; + /* + const unsigned zz = (kNumLogBits - 1) & + ((UInt32)0 - (((((UInt32)1 << kNumLogBits) - 1) - pos) >> 31)); + */ + const unsigned zz = (kNumLogBits - 1) & + (((((UInt32)1 << kNumLogBits) - 1) - pos) >> (31 - 3)); + return g_FastPos[pos >> zz] + (zz * 2); } + void CEncProps::Normalize() { int level = Level; @@ -253,13 +265,13 @@ NO_INLINE void CCoder::GetMatches() UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; - UInt32 numPairs = (_btMode) ? + const UInt32 numPairs = (UInt32)((_btMode ? Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp): - Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp); + Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp)) - distanceTmp); *m_MatchDistances = (UInt16)numPairs; - if (numPairs > 0) + if (numPairs != 0) { UInt32 i; for (i = 0; i < numPairs; i += 2) diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp index 5a6c6831..4b3acd30 100644 --- a/CPP/7zip/Compress/LzmaEncoder.cpp +++ b/CPP/7zip/Compress/LzmaEncoder.cpp @@ -112,12 +112,34 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) return S_OK; } + if (propID == NCoderPropID::kDictionarySize) + { + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit VT_UI8 for dictionary and (dict == 4 GiB) + const UInt64 v = prop.uhVal.QuadPart; + if (v > ((UInt64)1 << 32)) + return E_INVALIDARG; + UInt32 dict; + if (v == ((UInt64)1 << 32)) + dict = (UInt32)(Int32)-1; + else + dict = (UInt32)v; + ep.dictSize = dict; + return S_OK; + } + } + if (prop.vt != VT_UI4) return E_INVALIDARG; UInt32 v = prop.ulVal; switch (propID) { - case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break; + case NCoderPropID::kDefaultProp: + if (v > 32) + return E_INVALIDARG; + ep.dictSize = (v == 32) ? (UInt32)(Int32)-1 : (UInt32)1 << (unsigned)v; + break; SET_PROP_32(kLevel, level) SET_PROP_32(kNumFastBytes, fb) SET_PROP_32U(kMatchFinderCycles, mc) diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp index e2754772..d41d2aca 100644 --- a/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/CPP/7zip/Compress/PpmdEncoder.cpp @@ -59,7 +59,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID > NCoderPropID::kReduceSize) continue; if (propID == NCoderPropID::kReduceSize) @@ -68,16 +68,50 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA props.ReduceSize = (UInt32)prop.uhVal.QuadPart; continue; } + + if (propID == NCoderPropID::kUsedMemorySize) + { + // here we have selected (4 GiB - 1 KiB) as replacement for (4 GiB) MEM_SIZE. + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + UInt32 v; + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit values (for 4 GiB value) + const UInt64 v64 = prop.uhVal.QuadPart; + if (v64 > ((UInt64)1 << 32)) + return E_INVALIDARG; + if (v64 == ((UInt64)1 << 32)) + v = kPpmd_Default_4g; + else + v = (UInt32)v64; + } + else if (prop.vt == VT_UI4) + v = (UInt32)prop.ulVal; + else + return E_INVALIDARG; + if (v > PPMD7_MAX_MEM_SIZE) + v = kPpmd_Default_4g; + + /* here we restrict MEM_SIZE for Encoder. + It's for better performance of encoding and decoding. + The Decoder still supports more MEM_SIZE values. */ + if (v < ((UInt32)1 << 16) || (v & 3) != 0) + return E_INVALIDARG; + // if (v < PPMD7_MIN_MEM_SIZE) return E_INVALIDARG; // (1 << 11) + /* + Supported MEM_SIZE range : + [ (1 << 11) , 0xFFFFFFFF - 12 * 3 ] - current 7-Zip's Ppmd7 constants + [ 1824 , 0xFFFFFFFF ] - real limits of Ppmd7 code + */ + props.MemSize = v; + continue; + } + if (prop.vt != VT_UI4) return E_INVALIDARG; UInt32 v = (UInt32)prop.ulVal; switch (propID) { - case NCoderPropID::kUsedMemorySize: - if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0) - return E_INVALIDARG; - props.MemSize = v; - break; case NCoderPropID::kOrder: if (v < 2 || v > 32) return E_INVALIDARG; diff --git a/CPP/7zip/LzFindOpt.mak b/CPP/7zip/LzFindOpt.mak new file mode 100644 index 00000000..169e10f0 --- /dev/null +++ b/CPP/7zip/LzFindOpt.mak @@ -0,0 +1,7 @@ +!IF defined(USE_C_LZFINDOPT) || "$(PLATFORM)" != "x64" +C_OBJS = $(C_OBJS) \ + $O\LzFindOpt.obj +!ELSE +ASM_OBJS = $(ASM_OBJS) \ + $O\LzFindOpt.obj +!ENDIF diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index ef7eb1a7..00df80e9 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -1405,11 +1405,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) else if (options.Command.CommandType == NCommandType::kBenchmark) { options.NumIterations = 1; + options.NumIterations_Defined = false; if (curCommandIndex < numNonSwitchStrings) { if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]); curCommandIndex++; + options.NumIterations_Defined = true; } } else if (options.Command.CommandType == NCommandType::kHash) diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h index 150541e6..1e488d8c 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.h +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -109,6 +109,7 @@ struct CArcCmdLineOptions // Benchmark UInt32 NumIterations; + bool NumIterations_Defined; CArcCmdLineOptions(): HelpMode(false), diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp index 4e957331..fb4c1726 100644 --- a/CPP/7zip/UI/Common/Bench.cpp +++ b/CPP/7zip/UI/Common/Bench.cpp @@ -51,6 +51,7 @@ #include "../../../Common/StringToInt.h" #include "../../Common/MethodProps.h" +#include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" #include "Bench.h" @@ -87,20 +88,30 @@ static void SetComplexCommandsMs(UInt32 complexInMs, } } +// const UInt64 kBenchmarkUsageMult = 1000000; // for debug +static const unsigned kBenchmarkUsageMultBits = 16; +static const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits; + +UInt64 Benchmark_GetUsage_Percents(UInt64 usage) +{ + return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult; +} + static const unsigned kNumHashDictBits = 17; static const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test -static const unsigned kOldLzmaDictBits = 30; +static const unsigned kOldLzmaDictBits = 32; -static const UInt32 kAdditionalSize = (1 << 16); +// static const size_t kAdditionalSize = (size_t)1 << 32; // for debug +static const size_t kAdditionalSize = (size_t)1 << 16; static const UInt32 kCompressedAdditionalSize = (1 << 10); -static const UInt32 kMaxLzmaPropSize = 5; +static const UInt32 kMaxMethodPropSize = (1 << 6); #define ALLOC_WITH_HRESULT(_buffer_, _size_) \ { (_buffer_)->Alloc(_size_); \ - if (!(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; } + if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; } class CBaseRandomGenerator @@ -143,7 +154,7 @@ static void RandGen(Byte *buf, size_t size) } -class CBenchRandomGenerator: public CAlignedBuffer +class CBenchRandomGenerator: public CMidAlignedBuffer { static UInt32 GetVal(UInt32 &res, unsigned numBits) { @@ -172,14 +183,21 @@ public: void GenerateLz(unsigned dictBits, UInt32 salt) { CBaseRandomGenerator rg(salt); - UInt32 pos = 0; - UInt32 rep0 = 1; + size_t pos = 0; + size_t rep0 = 1; const size_t bufSize = Size(); Byte *buf = (Byte *)*this; unsigned posBits = 1; + + // printf("\n dictBits = %d\n", (UInt32)dictBits); + // printf("\n bufSize = 0x%p\n", (const void *)bufSize); while (pos < bufSize) { + /* + if (pos >= ((UInt32)1 << 31)) + printf(" %x\n", pos); + */ UInt32 r = rg.GetRnd(); if (GetVal(r, 1) == 0 || pos < 1024) buf[pos++] = (Byte)(r & 0xFF); @@ -192,7 +210,7 @@ public: { len += GetLen(r); - while (((UInt32)1 << posBits) < pos) + while (((size_t)1 << posBits) < pos) posBits++; unsigned numBitsMax = dictBits; @@ -206,11 +224,12 @@ public: for (;;) { - UInt32 ppp = GetVal(r, numLogBits) + kAddBits; + const UInt32 ppp = GetVal(r, numLogBits) + kAddBits; r = rg.GetRnd(); if (ppp > numBitsMax) continue; - rep0 = GetVal(r, ppp); + // rep0 = GetVal(r, ppp); + rep0 = r & (((size_t)1 << ppp) - 1); if (rep0 < pos) break; r = rg.GetRnd(); @@ -218,10 +237,11 @@ public: rep0++; } + // len *= 300; // for debug { - UInt32 rem = (UInt32)bufSize - pos; + const size_t rem = bufSize - pos; if (len > rem) - len = rem; + len = (UInt32)rem; } Byte *dest = buf + pos; const Byte *src = dest - rep0; @@ -230,6 +250,7 @@ public: *dest++ = *src++; } } + // printf("\n CRC = %x\n", CrcCalc(buf, bufSize)); } }; @@ -274,7 +295,7 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed class CBenchmarkOutStream: public ISequentialOutStream, - public CAlignedBuffer, + public CMidAlignedBuffer, public CMyUnknownImp { // bool _overflow; @@ -304,6 +325,8 @@ public: Crc = CrcUpdate(Crc, data, size); } + size_t GetPos() const { return Pos; } + // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } MY_UNKNOWN_IMP @@ -571,6 +594,7 @@ public: STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; + STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { HRESULT res = Status->GetResult(); @@ -578,6 +602,22 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 return res; if (!Callback) return res; + + /* + static UInt64 inSizePrev = 0; + static UInt64 outSizePrev = 0; + UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0; + if (inSize) { val1 = *inSize; delta1 = val1 - inSizePrev; inSizePrev = val1; } + if (outSize) { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2; } + UInt64 percents = delta2 * 1000; + if (delta1 != 0) + percents /= delta1; + printf("=== %7d %7d %7d %7d ratio = %4d\n", + (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10), + (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10), + (unsigned)percents); + */ + CBenchInfo info; SetFinishTime(info); if (Status->EncodeMode) @@ -599,18 +639,26 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 static const unsigned kSubBits = 8; -static UInt32 GetLogSize(UInt32 size) +static UInt32 GetLogSize(UInt64 size) { - for (unsigned i = kSubBits; i < 32; i++) - for (UInt32 j = 0; j < (1 << kSubBits); j++) - if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) - return (i << kSubBits) + j; - return (32 << kSubBits); + if (size <= 1) + return 0; + unsigned i; + for (i = 2; i < 64; i++) + if (size < ((UInt64)1 << i)) + break; + i--; + UInt32 v; + if (i <= kSubBits) + v = (UInt32)(size) << (kSubBits - i); + else + v = (UInt32)(size >> (i - kSubBits)); + return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1)); } static void NormalizeVals(UInt64 &v1, UInt64 &v2) { - while (v1 > 1000000) + while (v1 >= ((UInt32)1 << ((64 - kBenchmarkUsageMultBits) / 2))) { v1 >>= 1; v2 >>= 1; @@ -629,7 +677,7 @@ UInt64 CBenchInfo::GetUsage() const userFreq = 1; if (globalTime == 0) globalTime = 1; - return userTime * globalFreq * 1000000 / userFreq / globalTime; + return userTime * globalFreq * kBenchmarkUsageMult / userFreq / globalTime; } UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const @@ -659,9 +707,9 @@ static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq) return value * freq / elTime; } -UInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const +UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const { - return MyMultDiv64(numCommands, GlobalTime, GlobalFreq); + return MyMultDiv64(numUnits, GlobalTime, GlobalFreq); } struct CBenchProps @@ -694,7 +742,7 @@ struct CBenchProps return (packSize * DecComplexCompr + unpackSize * DecComplexUnc); } - UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); + UInt64 GetCompressRating(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); }; @@ -706,38 +754,50 @@ void CBenchProps::SetLzmaCompexity() LzmaRatingMode = true; } -UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) +UInt64 CBenchProps::GetCompressRating(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) { if (dictSize < (1 << kBenchMinDicLogSize)) dictSize = (1 << kBenchMinDicLogSize); UInt64 encComplex = EncComplex; if (LzmaRatingMode) { - UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits); + /* + for (UInt64 uu = 0; uu < (UInt64)0xf << 60;) + { + unsigned rr = GetLogSize(uu); + printf("\n%16I64x , log = %4x", uu, rr); + uu += 1; + uu += uu / 50; + } + */ + // throw 1; + const UInt32 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits); encComplex = 870 + ((t * t * 5) >> (2 * kSubBits)); } - UInt64 numCommands = (UInt64)size * encComplex; + const UInt64 numCommands = (UInt64)size * encComplex; return MyMultDiv64(numCommands, elapsedTime, freq); } UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) { - UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations; + const UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations; return MyMultDiv64(numCommands, elapsedTime, freq); } -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) + + +UInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const { CBenchProps props; props.SetLzmaCompexity(); - return props.GetCompressRating(dictSize, elapsedTime, freq, size); + return props.GetCompressRating(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); } -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) +UInt64 CBenchInfo::GetRating_LzmaDec() const { CBenchProps props; props.SetLzmaCompexity(); - return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations); + return props.GetDecompressRating(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); } @@ -880,10 +940,14 @@ struct CBenchSyncCommon -struct CEncoderInfo; +class CEncoderInfo; -struct CEncoderInfo +class CEncoderInfo { + CLASS_NO_COPY(CEncoderInfo) + +public: + #ifndef _7ZIP_ST NWindows::CThread thread[2]; NSynchronization::CManualResetEvent ReadyEvent; @@ -949,8 +1013,11 @@ struct CEncoderInfo const Byte *fileData; CBenchRandomGenerator rg; - CAlignedBuffer rgCopy; // it must be 16-byte aligned !!! - CBenchmarkOutStream *propStreamSpec; + CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!! + + // CBenchmarkOutStream *propStreamSpec; + Byte propsData[kMaxMethodPropSize]; + CBufPtrSeqOutStream *propStreamSpec; CMyComPtr<ISequentialOutStream> propStream; unsigned generateDictBits; @@ -1055,15 +1122,21 @@ struct CEncoderInfo }; + + +static size_t GetBenchCompressedSize(size_t bufferSize) +{ + return kCompressedAdditionalSize + bufferSize + bufferSize / 16; + // kBufferSize / 2; +} + + HRESULT CEncoderInfo::Generate() { const COneMethodInfo &method = _method; // we need extra space, if input data is already compressed - const size_t kCompressedBufferSize = - kCompressedAdditionalSize + - kBufferSize + kBufferSize / 16; - // kBufferSize / 2; + const size_t kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); if (kCompressedBufferSize < kBufferSize) return E_FAIL; @@ -1078,7 +1151,13 @@ HRESULT CEncoderInfo::Generate() if (generateDictBits == 0) rg.GenerateSimpleRandom(Salt); else + { + if (generateDictBits >= sizeof(size_t) * 8 + && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return E_INVALIDARG; rg.GenerateLz(generateDictBits, Salt); + // return E_ABORT; // for debug + } // printf("\n%d\n ", GetTickCount() - ttt); crc = CrcCalc((const Byte *)rg, rg.Size()); @@ -1101,11 +1180,12 @@ HRESULT CEncoderInfo::Generate() if (!propStream) { - propStreamSpec = new CBenchmarkOutStream; + propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream; propStream = propStreamSpec; } - ALLOC_WITH_HRESULT(propStreamSpec, kMaxLzmaPropSize); - propStreamSpec->Init(true, false); + // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize); + // propStreamSpec->Init(true, false); + propStreamSpec->Init(propsData, sizeof(propsData)); CMyComPtr<IUnknown> coder; @@ -1206,8 +1286,12 @@ static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size) HRESULT CEncoderInfo::Encode() { + // printf("\nCEncoderInfo::Generate\n"); + RINOK(Generate()); + // printf("\n2222\n"); + #ifndef _7ZIP_ST if (Common) { @@ -1359,7 +1443,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) CMyComPtr<ICompressSetDecoderProperties2> setDecProps; coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps); - if (!setDecProps && propStreamSpec->Pos != 0) + if (!setDecProps && propStreamSpec->GetPos() != 0) return E_FAIL; CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; @@ -1393,7 +1477,10 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) if (setDecProps) { - RINOK(setDecProps->SetDecoderProperties2((const Byte *)*propStreamSpec, (UInt32)propStreamSpec->Pos)); + RINOK(setDecProps->SetDecoderProperties2( + /* (const Byte *)*propStreamSpec, */ + propsData, + (UInt32)propStreamSpec->GetPos())); } { @@ -1918,16 +2005,36 @@ static HRESULT MethodBench( info.PackSize += encoder.compressedSize; } - RINOK(callback->SetDecodeResult(info, false)); + // RINOK(callback->SetDecodeResult(info, false)); // why we called before 21.03 ?? RINOK(callback->SetDecodeResult(info, true)); return S_OK; } -static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary) + +static inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog) { - UInt32 hs = dictionary - 1; + /* + if (dictSizeLog < 32) + return (UInt32)1 << dictSizeLog; + else + return (UInt32)(Int32)-1; + */ + return (UInt64)1 << dictSizeLog; +} + + +// it's limit of current LZMA implementation that can be changed later +#define kLzmaMaxDictSize ((UInt32)15 << 28) + +static inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict) +{ + if (dict == 0) + dict = 1; + if (dict > kLzmaMaxDictSize) + dict = kLzmaMaxDictSize; + UInt32 hs = (UInt32)dict - 1; hs |= (hs >> 1); hs |= (hs >> 2); hs |= (hs >> 4); @@ -1937,29 +2044,59 @@ static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary) if (hs > (1 << 24)) hs >>= 1; hs++; - return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + + hs += (1 << 16); + + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict + (1 << 16) + + (multiThread ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + + UInt64 son = (UInt64)dict; + if (btMode) + son *= 2; + const UInt64 v = (hs + son) * 4 + blockSize + (1 << 20) + (multiThread ? (6 << 20) : 0); + + // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20)); + // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20)); + return v; } -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench) + +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench) { - const UInt32 kBufferSize = dictionary; - const UInt32 kCompressedBufferSize = kBufferSize; // / 2; - bool lzmaMt = (totalBench || numThreads > 1); + const size_t kBufferSize = (size_t)dictionary + kAdditionalSize; + const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2; + if (level < 0) + level = 5; + const int algo = (level < 5 ? 0 : 1); + const int btMode = (algo == 0 ? 0 : 1); + UInt32 numBigThreads = numThreads; - if (!totalBench && lzmaMt) - numBigThreads /= 2; + bool lzmaMt = (totalBench || (numThreads > 1 && btMode)); + if (btMode) + { + if (!totalBench && lzmaMt) + numBigThreads /= 2; + } return ((UInt64)kBufferSize + kCompressedBufferSize + - GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads; + GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads; } +static UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary) +{ + // dictionary += (dictionary >> 9); // for page tables (virtual memory) + return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20); +} // ---------- CRC and HASH ---------- struct CCrcInfo_Base { - CAlignedBuffer Buffer; + CMidAlignedBuffer Buffer; const Byte *Data; size_t Size; bool CreateLocalBuf; @@ -2111,9 +2248,12 @@ static THREAD_FUNC_DECL FreqThreadFunction(void *param) UInt32 sum = g_BenchCpuFreqTemp; for (UInt64 k = p->NumIterations; k > 0; k--) { - p->CallbackRes = p->Callback->CheckBreak(); - if (p->CallbackRes != S_OK) - return 0; + if (p->Callback) + { + p->CallbackRes = p->Callback->CheckBreak(); + if (p->CallbackRes != S_OK) + return 0; + } sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp); } p->ValRes = sum; @@ -2437,27 +2577,6 @@ static const CBenchHash g_Hash[] = { 2, 5500, 0x85189d02, "BLAKE2sp" } }; -struct CTotalBenchRes -{ - // UInt64 NumIterations1; // for Usage - UInt64 NumIterations2; // for Rating / RPU - - UInt64 Rating; - UInt64 Usage; - UInt64 RPU; - - void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; } - - void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) - { - Rating = (r1.Rating + r2.Rating); - Usage = (r1.Usage + r2.Usage); - RPU = (r1.RPU + r2.RPU); - // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); - NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); - } -}; - static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) { char s[128]; @@ -2523,7 +2642,7 @@ static void PrintSpaces(IBenchPrintCallback &f, unsigned size) static void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size) { - PrintNumber(f, (usage + 5000) / 10000, size); + PrintNumber(f, Benchmark_GetUsage_Percents(usage), size); } static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq) @@ -2537,17 +2656,39 @@ static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt6 PrintSpaces(f, kFieldSize_EUAndEffec); else { - UInt64 ddd = cpuFreq * usage / 100; - /* - if (ddd == 0) - ddd = 1; - */ - PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU); + PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU); PrintPercents(f, rating, cpuFreq, kFieldSize_Effec); } } } + +void CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info) +{ + Speed = info.GetUnpackSizeSpeed(); + Usage = info.GetUsage(); + RPU = info.GetRatingPerUsage(Rating); +} + +void CTotalBenchRes::Mult_For_Weight(unsigned weight) +{ + NumIterations2 *= weight; + RPU *= weight; + Rating *= weight; + Usage += weight; + Speed += weight; +} + +void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r) +{ + Rating += r.Rating; + Usage += r.Usage; + RPU += r.RPU; + Speed += r.Speed; + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 += r.NumIterations2; +} + static void PrintResults(IBenchPrintCallback *f, const CBenchInfo &info, unsigned weight, @@ -2555,36 +2696,43 @@ static void PrintResults(IBenchPrintCallback *f, bool showFreq, UInt64 cpuFreq, CTotalBenchRes *res) { - UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations); + CTotalBenchRes t; + t.Rating = rating; + t.NumIterations2 = 1; + t.Generate_From_BenchInfo(info); + if (f) { - if (speed != 0) - PrintNumber(*f, speed / 1024, kFieldSize_Speed); + if (t.Speed != 0) + PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed); else PrintSpaces(*f, 1 + kFieldSize_Speed); } - UInt64 usage = info.GetUsage(); - UInt64 rpu = info.GetRatingPerUsage(rating); if (f) { - PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq); + PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq); } if (res) { // res->NumIterations1++; - res->NumIterations2 += weight; - res->RPU += (rpu * weight); - res->Rating += (rating * weight); - res->Usage += (usage * weight); + t.Mult_For_Weight(weight); + res->Update_With_Res(t); } } -static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res) +static void PrintTotals(IBenchPrintCallback &f, + bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res) { - PrintSpaces(f, 1 + kFieldSize_Speed); + const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1; + const UInt64 speed = res.Speed / numIterations2; + if (showSpeed && speed != 0) + PrintNumber(f, speed / 1024, kFieldSize_Speed); + else + PrintSpaces(f, 1 + kFieldSize_Speed); + + // PrintSpaces(f, 1 + kFieldSize_Speed); // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1; - UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1; PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq); } @@ -2649,7 +2797,7 @@ void Add_LargePages_String(AString &s) #ifdef _WIN32 if (g_LargePagesMode || g_LargePageSize != 0) { - s += " (LP-"; + s.Add_OptSpaced("(LP-"); PrintSize_KMGT_Or_Hex(s, g_LargePageSize); #ifdef MY_CPU_X86_OR_AMD64 if (CPU_IsSupported_PageGB()) @@ -2700,7 +2848,7 @@ struct CBenchCallbackToPrint: public IBenchCallback CTotalBenchRes EncodeRes; CTotalBenchRes DecodeRes; IBenchPrintCallback *_file; - UInt32 DictSize; + UInt64 DictSize; bool Use2Columns; unsigned NameFieldSize; @@ -2876,7 +3024,8 @@ struct CFreqBench UInt64 specifiedFreq; // out: - UInt64 cpuFreq; + UInt64 CpuFreqRes; + UInt64 UsageRes; UInt32 res; CFreqBench() @@ -2897,7 +3046,8 @@ HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file ) { res = 0; - cpuFreq = 0; + CpuFreqRes = 0; + UsageRes = 0; if (numThreads == 0) numThreads = 1; @@ -2984,17 +3134,17 @@ HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file info.PackSize = 0; info.NumIterations = 1; + const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity; + const UInt64 rating = info.GetSpeed(numCommands); + CpuFreqRes = rating / numThreads; + UsageRes = info.GetUsage(); + if (_file) { - { - UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity; - UInt64 rating = info.GetSpeed(numCommands); - cpuFreq = rating / numThreads; - PrintResults(_file, info, + PrintResults(_file, info, 0, // weight rating, - showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL); - } + showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL); RINOK(_file->CheckBreak()); } @@ -3041,7 +3191,7 @@ static HRESULT CrcBench( /* // if will generate random data in each thread, instead of global data - CAlignedBuffer buffer; + CMidAlignedBuffer buffer; if (!fileData) { ALLOC_WITH_HRESULT(&buffer, bufferSize) @@ -3288,10 +3438,10 @@ HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS IBenchPrintCallback *printCallback, IBenchCallback *benchCallback, - // IBenchFreqCallback *freqCallback, const CObjectVector<CProperty> &props, UInt32 numIterations, - bool multiDict) + bool multiDict, + IBenchFreqCallback *freqCallback) { if (!CrcInternalTest()) return E_FAIL; @@ -3342,7 +3492,9 @@ HRESULT Bench( COneMethodInfo method; - CAlignedBuffer fileDataBuffer; + CMidAlignedBuffer fileDataBuffer; + bool use_fileData = false; + bool isFixedDict = false; { unsigned i; @@ -3395,7 +3547,10 @@ HRESULT Bench( return E_INVALIDARG; } + // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here + ALLOC_WITH_HRESULT(&fileDataBuffer, len); + use_fileData = true; { size_t processed; @@ -3436,9 +3591,14 @@ HRESULT Bench( continue; } - if (name.IsEqualTo("ds")) + const bool isCurrent_fixedDict = name.IsEqualTo("df"); + if (isCurrent_fixedDict) + isFixedDict = true; + if (isCurrent_fixedDict || name.IsEqualTo("ds")) { RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog)); + if (startDicLog > 32) + return E_INVALIDARG; startDicLog_Defined = true; continue; } @@ -3505,6 +3665,15 @@ HRESULT Bench( if (printCallback) { AString s; + + #ifndef _WIN32 + s += "Compiler: "; + GetCompiler(s); + printCallback->Print(s); + printCallback->NewLine(); + s.Empty(); + #endif + GetSystemInfoText(s); printCallback->Print(s); printCallback->NewLine(); @@ -3512,10 +3681,10 @@ HRESULT Bench( if (printCallback) { - printCallback->Print("CPU Freq:"); + printCallback->Print("1T CPU Freq (MHz):"); } - if (printCallback /* || freqCallback */) + if (printCallback || freqCallback) { UInt64 numMilCommands = 1 << 6; if (specifiedFreq != 0) @@ -3543,6 +3712,7 @@ HRESULT Bench( start = 1; const UInt64 freq = GetFreq(); // mips is constant in some compilers + const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, start, freq); const UInt64 mipsVal = numMilCommands * freq / start; if (printCallback) { @@ -3556,10 +3726,10 @@ HRESULT Bench( PrintNumber(*printCallback, mipsVal, 5); } } - /* if (freqCallback) - freqCallback->AddCpuFreq(mipsVal); - */ + { + RINOK(freqCallback->AddCpuFreq(1, hz, kBenchmarkUsageMult)); + } if (jj >= 1) { @@ -3573,7 +3743,10 @@ HRESULT Bench( if (start >= freq * 16) { printCallback->Print(" (Cmplx)"); - needSetComplexity = true; + if (!freqCallback) // we don't want complexity change for old gui lzma benchmark + { + needSetComplexity = true; + } needStop = true; } if (needSetComplexity) @@ -3583,8 +3756,110 @@ HRESULT Bench( numMilCommands <<= 1; } } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(1)); + } + } + + if (numThreadsSpecified >= 2) + if (printCallback || freqCallback) + { + if (printCallback) + printCallback->NewLine(); + + /* it can show incorrect frequency for HT threads. + so we reduce freq test to (numCPUs / 2) */ + + UInt32 numThreads = numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2: numThreadsSpecified; + if (numThreads < 1) + numThreads = 1; + + if (printCallback) + { + char s[128]; + ConvertUInt64ToString(numThreads, s); + printCallback->Print(s); + printCallback->Print("T CPU Freq (MHz):"); + } + UInt64 numMilCommands = 1 << 10; + if (specifiedFreq != 0) + { + while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) + numMilCommands >>= 1; + } + + for (int jj = 0;; jj++) + { + if (printCallback) + RINOK(printCallback->CheckBreak()); + + { + // PrintLeft(f, "CPU", kFieldSize_Name); + + // UInt32 resVal; + + CFreqBench fb; + fb.complexInCommands = numMilCommands * 1000000; + fb.numThreads = numThreads; + // showFreq; + // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); + fb.showFreq = true; + fb.specifiedFreq = 1; + + HRESULT res = fb.FreqBench(NULL /* printCallback */ + #ifndef _7ZIP_ST + , &affinityMode + #endif + ); + RINOK(res); + + if (freqCallback) + { + RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes)); + } + + if (printCallback) + { + /* + if (realDelta == 0) + { + printCallback->Print(" -"); + } + else + */ + { + // PrintNumber(*printCallback, start, 0); + PrintUsage(*printCallback, fb.UsageRes, 3); + printCallback->Print("%"); + PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0); + printCallback->Print(" "); + + // PrintNumber(*printCallback, fb.UsageRes, 5); + } + } + } + // if (jj >= 1) + { + bool needStop = (numMilCommands >= (1 << + #ifdef _DEBUG + 7 + #else + 11 + #endif + )); + if (needStop) + break; + numMilCommands <<= 1; + } + } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(numThreads)); + } } + if (printCallback) { printCallback->NewLine(); @@ -3597,8 +3872,10 @@ HRESULT Bench( if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax) return E_INVALIDARG; - UInt32 dict; - bool dictIsDefined = method.Get_DicSize(dict); + UInt64 dict = (UInt64)1 << startDicLog; + const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict)); + + const int level = method.GetLevel(); if (method.MethodName.IsEmpty()) method.MethodName = "LZMA"; @@ -3607,8 +3884,20 @@ HRESULT Bench( { CBenchProps benchProps; benchProps.SetLzmaCompexity(); - UInt32 dictSize = method.Get_Lzma_DicSize(); - UInt32 uncompressedDataSize = kAdditionalSize + dictSize; + const UInt64 dictSize = method.Get_Lzma_DicSize(); + + size_t uncompressedDataSize; + if (use_fileData) + { + uncompressedDataSize = fileDataBuffer.Size(); + } + else + { + uncompressedDataSize = kAdditionalSize + (size_t)dictSize; + if (uncompressedDataSize < dictSize) + return E_INVALIDARG; + } + return MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, @@ -3636,7 +3925,7 @@ HRESULT Bench( UInt64 dict64 = dict; if (!dictIsDefined) dict64 = (1 << 27); - if (fileDataBuffer.IsAllocated()) + if (use_fileData) { if (!dictIsDefined) dict64 = fileDataBuffer.Size(); @@ -3684,13 +3973,15 @@ HRESULT Bench( { UInt64 usage = 1 << 20; UInt64 bufSize = dict64; - if (fileDataBuffer.IsAllocated()) + if (use_fileData) { usage += fileDataBuffer.Size(); if (bufSize > fileDataBuffer.Size()) bufSize = fileDataBuffer.Size(); + #ifndef _7ZIP_ST if (numThreadsSpecified != 1) usage += bufSize * numThreadsSpecified * (k_Crc_CreateLocalBuf_For_File ? 1 : 0); + #endif } else usage += numThreadsSpecified * bufSize; @@ -3776,7 +4067,7 @@ HRESULT Bench( PrintRight(f, s, 4); size_t dataSize = fileDataBuffer.Size(); - if (dataSize > bufSize || !fileDataBuffer.IsAllocated()) + if (dataSize > bufSize || !use_fileData) dataSize = (size_t)bufSize; FOR_VECTOR (ti, numThreadsVector) @@ -3792,7 +4083,7 @@ HRESULT Bench( speed, usage, complexity, 1, // benchWeight, - (pow == kNumHashDictBits && !fileDataBuffer.IsAllocated()) ? checkSum : NULL, + (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL, method, &f, #ifndef _7ZIP_ST @@ -3880,7 +4171,7 @@ HRESULT Bench( f.NewLine(); } - if (!dictIsDefined) + if (!dictIsDefined && !onlyHashBench) { const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); unsigned dicSizeLog = dicSizeLog_Main; @@ -3891,10 +4182,10 @@ HRESULT Bench( if (ramSize_Defined) for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) + if (GetBenchMemoryUsage(numThreads, level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) break; - dict = (UInt32)1 << dicSizeLog; + dict = (UInt64)1 << dicSizeLog; if (totalBenchMode && dicSizeLog != dicSizeLog_Main) { @@ -3904,7 +4195,12 @@ HRESULT Bench( } } - Print_Usage_and_Threads(f, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), numThreads); + Print_Usage_and_Threads(f, + onlyHashBench ? + GetBenchMemoryUsage_Hash(numThreads, dict) : + GetBenchMemoryUsage(numThreads, level, dict, totalBenchMode), + numThreads); + f.NewLine(); f.NewLine(); @@ -3988,6 +4284,7 @@ HRESULT Bench( if (specifiedFreq != 0) cpuFreq = specifiedFreq; + // bool showTotalSpeed = false; if (totalBenchMode) { @@ -4017,7 +4314,7 @@ HRESULT Bench( ); RINOK(res); - cpuFreq = fb.cpuFreq; + cpuFreq = fb.CpuFreqRes; callback.NewLine(); if (specifiedFreq != 0) @@ -4037,12 +4334,12 @@ HRESULT Bench( if (!onlyHashBench) { - size_t dataSize = dict; - if (fileDataBuffer.IsAllocated()) + size_t dataSize = (size_t)dict; + if (use_fileData) { dataSize = fileDataBuffer.Size(); if (dictIsDefined && dataSize > dict) - dataSize = dict; + dataSize = (size_t)dict; } HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS @@ -4051,7 +4348,7 @@ HRESULT Bench( numThreads, &affinityMode, #endif - dictIsDefined || fileDataBuffer.IsAllocated(), // forceUnpackSize + dictIsDefined || use_fileData, // forceUnpackSize dataSize, (const Byte *)fileDataBuffer, printCallback, &callback); @@ -4061,12 +4358,16 @@ HRESULT Bench( { size_t dataSize = (size_t)1 << kNumHashDictBits; if (dictIsDefined) - dataSize = dict; - if (fileDataBuffer.IsAllocated()) + { + dataSize = (size_t)dict; + if (dataSize != dict) + return E_OUTOFMEMORY; + } + if (use_fileData) { dataSize = fileDataBuffer.Size(); if (dictIsDefined && dataSize > dict) - dataSize = dict; + dataSize = (size_t)dict; } HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads, @@ -4143,12 +4444,12 @@ HRESULT Bench( for (unsigned i = 0; i < numIterations; i++) { - unsigned pow = (dict < ((UInt32)1 << startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog; + unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog; if (!multiDict) - pow = 31; - while (((UInt32)1 << pow) > dict && pow > 0) + pow = 32; + while (GetDictSizeFromLog(pow) > dict && pow > 0) pow--; - for (; ((UInt32)1 << pow) <= dict; pow++) + for (; GetDictSizeFromLog(pow) <= dict; pow++) { char s[16]; ConvertUInt32ToString(pow, s); @@ -4156,7 +4457,7 @@ HRESULT Bench( s[pos++] = ':'; s[pos] = 0; PrintLeft(f, s, kFieldSize_SmallName); - callback.DictSize = (UInt32)1 << pow; + callback.DictSize = (UInt64)1 << pow; COneMethodInfo method2 = method; @@ -4170,13 +4471,15 @@ HRESULT Bench( } size_t uncompressedDataSize; - if (fileDataBuffer.IsAllocated()) + if (use_fileData) { uncompressedDataSize = fileDataBuffer.Size(); } else { - uncompressedDataSize = callback.DictSize; + uncompressedDataSize = (size_t)callback.DictSize; + if (uncompressedDataSize != callback.DictSize) + return E_OUTOFMEMORY; if (uncompressedDataSize >= (1 << 18)) uncompressedDataSize += kAdditionalSize; } @@ -4212,16 +4515,19 @@ HRESULT Bench( if (use2Columns) { PrintLeft(f, "Avr:", callback.NameFieldSize); - PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes); f.Print(kSep); - PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes); f.NewLine(); } PrintLeft(f, "Tot:", callback.NameFieldSize); CTotalBenchRes midRes; - midRes.SetSum(callback.EncodeRes, callback.DecodeRes); - PrintTotals(f, showFreq, cpuFreq, midRes); + midRes = callback.EncodeRes; + midRes.Update_With_Res(callback.DecodeRes); + + // midRes.SetSum(callback.EncodeRes, callback.DecodeRes); + PrintTotals(f, showFreq, cpuFreq, false, midRes); f.NewLine(); } diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h index 02f443e3..ab0c3048 100644 --- a/CPP/7zip/UI/Common/Bench.h +++ b/CPP/7zip/UI/Common/Bench.h @@ -8,6 +8,8 @@ #include "../../Common/CreateCoder.h" #include "../../UI/Common/Property.h" +UInt64 Benchmark_GetUsage_Percents(UInt64 usage); + struct CBenchInfo { UInt64 GlobalTime; @@ -17,26 +19,71 @@ struct CBenchInfo UInt64 UnpackSize; UInt64 PackSize; UInt64 NumIterations; + + /* + during Code(): we track benchInfo only from one thread (theads with index[0]) + NumIterations means number of threads + UnpackSize and PackSize are total sizes of all iterations of current thread + after Code(): + NumIterations means the number of Iterations + UnpackSize and PackSize are total sizes of all threads + */ CBenchInfo(): NumIterations(0) {} + UInt64 GetUsage() const; UInt64 GetRatingPerUsage(UInt64 rating) const; - UInt64 GetSpeed(UInt64 numCommands) const; + UInt64 GetSpeed(UInt64 numUnits) const; + UInt64 GetUnpackSizeSpeed() const { return GetSpeed(UnpackSize * NumIterations); } + + UInt64 Get_UnpackSize_Full() const { return UnpackSize * NumIterations; } + + UInt64 GetRating_LzmaEnc(UInt64 dictSize) const; + UInt64 GetRating_LzmaDec() const; }; + +struct CTotalBenchRes +{ + // UInt64 NumIterations1; // for Usage + UInt64 NumIterations2; // for Rating / RPU + + UInt64 Rating; + UInt64 Usage; + UInt64 RPU; + UInt64 Speed; + + void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; Speed = 0; } + + void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) + { + Rating = (r1.Rating + r2.Rating); + Usage = (r1.Usage + r2.Usage); + RPU = (r1.RPU + r2.RPU); + Speed = (r1.Speed + r2.Speed); + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); + } + + void Generate_From_BenchInfo(const CBenchInfo &info); + void Mult_For_Weight(unsigned weight); + void Update_With_Res(const CTotalBenchRes &r); +}; + + + struct IBenchCallback { - virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; + // virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; }; -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); + const unsigned kBenchMinDicLogSize = 18; -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false); +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench); struct IBenchPrintCallback { @@ -45,22 +92,20 @@ struct IBenchPrintCallback virtual HRESULT CheckBreak() = 0; }; -/* struct IBenchFreqCallback { - virtual void AddCpuFreq(UInt64 freq) = 0; + virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) = 0; + virtual HRESULT FreqsFinished(unsigned numThreads) = 0; }; -*/ HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS IBenchPrintCallback *printCallback, IBenchCallback *benchCallback, - // IBenchFreqCallback *freqCallback, const CObjectVector<CProperty> &props, UInt32 numIterations, - bool multiDict - ); + bool multiDict, + IBenchFreqCallback *freqCallback = NULL); AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti); diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp index cbb5dcc9..8943e7d9 100644 --- a/CPP/7zip/UI/Common/CompressCall2.cpp +++ b/CPP/7zip/UI/Common/CompressCall2.cpp @@ -272,7 +272,11 @@ void Benchmark(bool totalMode) prop.Value = "*"; props.Add(prop); } - result = Benchmark(EXTERNAL_CODECS_VARS_L props, g_HWND); + result = Benchmark( + EXTERNAL_CODECS_VARS_L + props, + k_NumBenchIterations_Default, + g_HWND); MY_TRY_FINISH } diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp index 8c24aaff..e7d9fd1b 100644 --- a/CPP/7zip/UI/Console/Main.cpp +++ b/CPP/7zip/UI/Console/Main.cpp @@ -128,7 +128,7 @@ static const char * const kHelpString = #ifndef _NO_CRYPTO " -p{Password} : set Password\n" #endif - " -r[-|0] : Recurse subdirectories\n" + " -r[-|0] : Recurse subdirectories for name search\n" " -sa{a|e|s} : set Archive name mode\n" " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" @@ -200,63 +200,55 @@ static void ShowProgInfo(CStdOutStream *so) #endif */ - #ifdef __VERSION__ - << " compiler: " << __VERSION__ - #endif - - #ifdef __GNUC__ - << " GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ - #endif - - #ifdef __clang__ - << " CLANG " << __clang_major__ << "." << __clang_minor__ - #endif - - #ifdef __xlC__ - << " XLC " << (__xlC__ >> 8) << "." << (__xlC__ & 0xFF) - #ifdef __xlC_ver__ - << "." << (__xlC_ver__ >> 8) << "." << (__xlC_ver__ & 0xFF) - #endif - #endif - - #ifdef _MSC_VER - << " MSC " << _MSC_VER - #endif - - #ifdef __ARM_FEATURE_CRC32 - << " CRC32" - #endif - << " " << (unsigned)(sizeof(void *)) * 8 << "-bit" #ifdef __ILP32__ << " ILP32" #endif - + #ifdef __ARM_ARCH << " arm_v:" << __ARM_ARCH #ifdef __ARM_ARCH_ISA_THUMB << " thumb:" << __ARM_ARCH_ISA_THUMB #endif #endif + ; + #ifdef ENV_HAVE_LOCALE - << " locale=" << GetLocale() + *so << " locale=" << GetLocale(); #endif #ifndef _WIN32 - << " UTF8=" << (IsNativeUTF8() ? "+" : "-") - << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-") - << " wchar_t=" << (unsigned)(sizeof(wchar_t)) * 8 << "-bit" - << " Files=" << (unsigned)(sizeof(off_t)) * 8 << "-bit" + { + const bool is_IsNativeUTF8 = IsNativeUTF8(); + if (!is_IsNativeUTF8) + *so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-"); + } + if (!g_ForceToUTF8) + *so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-"); + { + const unsigned wchar_t_size = (unsigned)sizeof(wchar_t); + if (wchar_t_size != 4) + *so << " wchar_t=" << wchar_t_size * 8 << "-bit"; + } + { + const unsigned off_t_size = (unsigned)sizeof(off_t); + if (off_t_size != 8) + *so << " Files=" << off_t_size * 8 << "-bit"; + } #endif - ; { const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors(); *so << " Threads:" << numCpus; } + #ifdef _7ZIP_ASM + *so << ", ASM"; + #endif + + /* { AString s; GetCpuName(s); @@ -264,9 +256,10 @@ static void ShowProgInfo(CStdOutStream *so) *so << ", " << s; } - #ifdef _7ZIP_ASM - *so << ",ASM"; + #ifdef __ARM_FEATURE_CRC32 + << " CRC32" #endif + #if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64)) if (CPU_IsSupported_AES()) *so << ",AES"; @@ -281,6 +274,7 @@ static void ShowProgInfo(CStdOutStream *so) if (CPU_IsSupported_SHA2()) *so << ",SHA2"; #endif #endif + */ *so << endl; } diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp index b3455cf5..082902e2 100644 --- a/CPP/7zip/UI/FileManager/AboutDialog.cpp +++ b/CPP/7zip/UI/FileManager/AboutDialog.cpp @@ -19,7 +19,7 @@ static const UInt32 kLangIDs[] = IDT_ABOUT_INFO }; -#define kHomePageURL TEXT("http://www.7-zip.org/") +#define kHomePageURL TEXT("https://www.7-zip.org/") #define kHelpTopic "start.htm" #define LLL_(quote) L##quote diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp index 1bf115ad..b688a901 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp @@ -136,8 +136,11 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { case kCloseMessage: { - KillTimer(_timer); - _timer = 0; + if (_timer) + { + KillTimer(kTimerID); + _timer = 0; + } if (_inCancelMessageBox) { _externalCloseMessageWasReceived = true; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 8e2d7c75..7b132468 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -348,7 +348,9 @@ bool CProgressDialog::OnInit() INIT_AS_UNDEFINED(_processed_Prev); INIT_AS_UNDEFINED(_packed_Prev); INIT_AS_UNDEFINED(_ratio_Prev); + _filesStr_Prev.Empty(); + _filesTotStr_Prev.Empty(); _foreground = true; @@ -423,13 +425,14 @@ static const UINT kIDs[] = IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL, IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL, IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL, - IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL, + 0, IDT_PROGRESS_FILES_TOTAL, IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL, IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL, IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL, IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL, - IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL + IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL, + IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL }; bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) @@ -546,6 +549,7 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) yPos = my; x = mx + gSize + padSize; } + if (kIDs[i] != 0) MoveItem(kIDs[i], x, yPos, labelSize, sY); MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY); yPos += sStep; @@ -617,6 +621,7 @@ static void ConvertSizeToString(UInt64 v, wchar_t *s) s += MyStringLen(s); *s++ = ' '; *s++ = c; + *s++ = 'B'; *s++ = 0; } } @@ -829,16 +834,24 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { wchar_t s[64]; + ConvertUInt64ToString(completedFiles, s); + if (_filesStr_Prev != s) + { + _filesStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_VAL, s); + } + + s[0] = 0; if (IS_DEFINED_VAL(totalFiles)) { - MyStringCat(s, L" / "); + MyStringCopy(s, L" / "); ConvertUInt64ToString(totalFiles, s + MyStringLen(s)); } - if (_filesStr_Prev != s) + if (_filesTotStr_Prev != s) { - _filesStr_Prev = s; - SetItemText(IDT_PROGRESS_FILES_VAL, s); + _filesTotStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_TOTAL, s); } } @@ -1024,8 +1037,13 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { case kCloseMessage: { - KillTimer(_timer); - _timer = 0; + if (_timer) + { + /* 21.03 : KillTimer(kTimerID) instead of KillTimer(_timer). + But (_timer == kTimerID) in Win10. So it worked too */ + KillTimer(kTimerID); + _timer = 0; + } if (_inCancelMessageBox) { _externalCloseMessageWasReceived = true; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h index fc032cd9..c17dd395 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -169,7 +169,9 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UInt64 _processed_Prev; UInt64 _packed_Prev; UInt64 _ratio_Prev; + UString _filesStr_Prev; + UString _filesTotStr_Prev; unsigned _prevSpeed_MoveBits; UInt64 _prevSpeed; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h index b45d7b49..736c7179 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -28,6 +28,7 @@ #define IDT_PROGRESS_PACKED_VAL 110 #define IDT_PROGRESS_FILES_VAL 111 +#define IDT_PROGRESS_FILES_TOTAL 112 #define IDT_PROGRESS_ELAPSED_VAL 120 #define IDT_PROGRESS_REMAINING_VAL 121 @@ -41,7 +42,7 @@ #ifdef UNDER_CE #define MY_PROGRESS_VAL_UNITS 44 #else -#define MY_PROGRESS_VAL_UNITS 76 +#define MY_PROGRESS_VAL_UNITS 72 #endif #define MY_PROGRESS_LABEL_UNITS_MIN 60 #define MY_PROGRESS_LABEL_UNITS_START 90 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc index c183af82..d2fee8cf 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc +++ b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc @@ -47,27 +47,32 @@ CAPTION "Progress" PUSHBUTTON "&Pause", IDB_PAUSE, bx2, by, bxs, bys PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8 LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8 LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8 - LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, m, y3, x0s, 8 + LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8 + LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8 LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8 LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8 LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8 + LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, x2, y4, x2s, 8 + RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX - RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_FILES_TOTAL x1, y3, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_RATIO_VAL, x3, y4, x3s, MY_TEXT_NOPREFIX LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp index 94dfab4c..41e0927d 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp @@ -10,15 +10,27 @@ #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Windows/Synchronization.h" #include "../../../Windows/System.h" #include "../../../Windows/Thread.h" +#include "../../../Windows/SystemInfo.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" #include "../../Common/MethodProps.h" +#include "../FileManager/DialogSize.h" #include "../FileManager/HelpUtils.h" +#ifdef LANG +#include "../FileManager/LangUtils.h" +#endif #include "../../MyVersion.h" +#include "../Common/Bench.h" + +#include "BenchmarkDialogRes.h" #include "BenchmarkDialog.h" using namespace NWindows; @@ -26,13 +38,350 @@ using namespace NWindows; #define kHelpTopic "fm/benchmark.htm" static const UINT_PTR kTimerID = 4; -static const UINT kTimerElapse = 1000; +static const UINT kTimerElapse = 1000; // 1000 + +// use PRINT_ITER_TIME to show time of each iteration in log box +// #define PRINT_ITER_TIME + +static const unsigned kRatingVector_NumBundlesMax = 20; + +enum MyBenchMessages +{ + k_Message_Finished = WM_APP + 1 +}; + +enum My_Message_WPARAM +{ + k_Msg_WPARM_Thread_Finished = 0, + k_Msg_WPARM_Iter_Finished, + k_Msg_WPARM_Enc1_Finished +}; + + +struct CBenchPassResult +{ + CTotalBenchRes Enc; + CTotalBenchRes Dec; + #ifdef PRINT_ITER_TIME + DWORD Ticks; + #endif + // CBenchInfo EncInfo; // for debug + // CBenchPassResult() {}; +}; + + +struct CTotalBenchRes2: public CTotalBenchRes +{ + UInt64 UnpackSize; + + void Init() + { + CTotalBenchRes::Init(); + UnpackSize = 0; + } + + void SetFrom_BenchInfo(const CBenchInfo &info) + { + NumIterations2 = 1; + Generate_From_BenchInfo(info); + UnpackSize = info.Get_UnpackSize_Full(); + } + + void Update_With_Res2(const CTotalBenchRes2 &r) + { + Update_With_Res(r); + UnpackSize += r.UnpackSize; + } +}; + + +struct CSyncData +{ + UInt32 NumPasses_Finished; + + // UInt64 NumEncProgress; // for debug + // UInt64 NumDecProgress; // for debug + // CBenchInfo EncInfo; // for debug + + CTotalBenchRes2 Enc_BenchRes_1; + CTotalBenchRes2 Enc_BenchRes; + + CTotalBenchRes2 Dec_BenchRes_1; + CTotalBenchRes2 Dec_BenchRes; + + #ifdef PRINT_ITER_TIME + DWORD TotalTicks; + #endif + + int RatingVector_DeletedIndex; + // UInt64 RatingVector_NumDeleted; + + bool BenchWasFinished; // all passes were finished + bool NeedPrint_Freq; + bool NeedPrint_RatingVector; + bool NeedPrint_Enc_1; + bool NeedPrint_Enc; + bool NeedPrint_Dec_1; + bool NeedPrint_Dec; + bool NeedPrint_Tot; // intermediate Total was updated after current pass + + void Init(); +}; + + +void CSyncData::Init() +{ + NumPasses_Finished = 0; + + // NumEncProgress = 0; + // NumDecProgress = 0; + + Enc_BenchRes.Init(); + Enc_BenchRes_1.Init(); + Dec_BenchRes.Init(); + Dec_BenchRes_1.Init(); + + #ifdef PRINT_ITER_TIME + TotalTicks = 0; + #endif + + RatingVector_DeletedIndex = -1; + // RatingVector_NumDeleted = 0; + + BenchWasFinished = + NeedPrint_Freq = + NeedPrint_RatingVector = + NeedPrint_Enc_1 = + NeedPrint_Enc = + NeedPrint_Dec_1 = + NeedPrint_Dec = + NeedPrint_Tot = false; +}; + + +struct CBenchProgressSync +{ + bool Exit; // GUI asks BenchThread to Exit, and BenchThread reads that variable + UInt32 NumThreads; + UInt64 DictSize; + UInt32 NumPasses_Limit; + int Level; + + // must be written by benchmark thread, read by GUI thread */ + CSyncData sd; + CRecordVector<CBenchPassResult> RatingVector; + + NWindows::NSynchronization::CCriticalSection CS; + + AString Text; + bool TextWasChanged; + + /* BenchFinish_Task_HRESULT - for result from benchmark code + BenchFinish_Thread_HRESULT - for Exceptions and service errors + these arreos must be shown even if user escapes benchmark */ + + HRESULT BenchFinish_Task_HRESULT; + HRESULT BenchFinish_Thread_HRESULT; + + UInt32 NumFreqThreadsPrev; + UString FreqString_Sync; + UString FreqString_GUI; + + CBenchProgressSync() + { + NumPasses_Limit = 1; + } + + void Init(); + + void SendExit() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + Exit = true; + } +}; + + +void CBenchProgressSync::Init() +{ + Exit = false; + + BenchFinish_Task_HRESULT = S_OK; + BenchFinish_Thread_HRESULT = S_OK; + + sd.Init(); + RatingVector.Clear(); + + NumFreqThreadsPrev = 0; + FreqString_Sync.Empty(); + FreqString_GUI.Empty(); + + Text.Empty(); + TextWasChanged = true; +} + + + +struct CMyFont +{ + HFONT _font; + CMyFont(): _font(NULL) {} + ~CMyFont() + { + if (_font) + DeleteObject(_font); + } + void Create(const LOGFONT *lplf) + { + _font = CreateFontIndirect(lplf); + } +}; + + +class CBenchmarkDialog; + +struct CThreadBenchmark +{ + CBenchmarkDialog *BenchmarkDialog; + DECL_EXTERNAL_CODECS_LOC_VARS2; + // HRESULT Result; + + HRESULT Process(); + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + /* ((CThreadBenchmark *)param)->Result = */ + ((CThreadBenchmark *)param)->Process(); + return 0; + } +}; + + +class CBenchmarkDialog: + public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox m_Dictionary; + NWindows::NControl::CComboBox m_NumThreads; + NWindows::NControl::CComboBox m_NumPasses; + NWindows::NControl::CEdit _consoleEdit; + UINT_PTR _timer; + + UInt32 _startTime; + UInt32 _finishTime; + bool _finishTime_WasSet; + + bool WasStopped_in_GUI; + bool ExitWasAsked_in_GUI; + bool NeedRestart; + + CMyFont _font; + + UInt64 RamSize; + UInt64 RamSize_Limit; + bool RamSize_Defined; + + UInt32 NumPasses_Finished_Prev; + + UString ElapsedSec_Prev; + + void InitSyncNew() + { + NumPasses_Finished_Prev = (UInt32)(Int32)-1; + ElapsedSec_Prev.Empty(); + Sync.Init(); + } + + virtual bool OnInit(); + virtual bool OnDestroy(); + virtual bool OnSize(WPARAM /* wParam */, int xSize, int ySize); + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCommand(int code, int itemID, LPARAM lParam); + virtual void OnHelp(); + virtual void OnCancel(); + virtual bool OnTimer(WPARAM timerID, LPARAM callback); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + + void Disable_Stop_Button(); + void OnStopButton(); + void RestartBenchmark(); + void StartBenchmark(); + + void UpdateGui(); + + void PrintTime(); + void PrintRating(UInt64 rating, UINT controlID); + void PrintUsage(UInt64 usage, UINT controlID); + void PrintBenchRes(const CTotalBenchRes2 &info, const UINT ids[]); + + UInt32 GetNumberOfThreads(); + size_t OnChangeDictionary(); + + void SetItemText_Number(int itemID, UInt64 val, LPCTSTR post = NULL); + void Print_MemUsage(UString &s, UInt64 memUsage) const; + bool IsMemoryUsageOK(UInt64 memUsage) const + { return memUsage + (1 << 20) <= RamSize_Limit; } + + void MyKillTimer(); + + void SendExit_Status(const wchar_t *message) + { + SetItemText(IDT_BENCH_ERROR_MESSAGE, message); + Sync.SendExit(); + } + +public: + CBenchProgressSync Sync; + + bool TotalMode; + CObjectVector<CProperty> Props; + + CSysString Bench2Text; + + NWindows::CThread _thread; + CThreadBenchmark _threadBenchmark; + + CBenchmarkDialog(): + _timer(0), + TotalMode(false), + WasStopped_in_GUI(false), + ExitWasAsked_in_GUI(false), + NeedRestart(false) + {} + + ~CBenchmarkDialog(); + + bool PostMsg_Finish(LPARAM param) + { + if ((HWND)*this) + return PostMsg(k_Message_Finished, param); + // the (HWND)*this is NULL only for some internal code failure + return true; + } + + INT_PTR Create(HWND wndParent = 0) + { + BIG_DIALOG_SIZE(332, 228); + return CModalDialog::Create(TotalMode ? IDD_BENCH_TOTAL : SIZED_DIALOG(IDD_BENCH), wndParent); + } + void MessageBoxError(LPCWSTR message) + { + MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR); + } + void MessageBoxError_Status(LPCWSTR message) + { + UString s ("ERROR: "); + s += message; + MessageBoxError(s); + SetItemText(IDT_BENCH_ERROR_MESSAGE, s); + } +}; + + + + + + -#ifdef LANG -#include "../FileManager/LangUtils.h" -#endif -using namespace NWindows; UString HResultToMessage(HRESULT errorCode); @@ -65,36 +414,48 @@ static const UInt32 kLangIDs_Colon[] = #endif static LPCTSTR const kProcessingString = TEXT("..."); +static LPCTSTR const kGB = TEXT(" GB"); static LPCTSTR const kMB = TEXT(" MB"); -static LPCTSTR const kMIPS = TEXT(" MIPS"); +static LPCTSTR const kKB = TEXT(" KB"); +// static LPCTSTR const kMIPS = TEXT(" MIPS"); static LPCTSTR const kKBs = TEXT(" KB/s"); -static const unsigned kMinDicLogSize = - #ifdef UNDER_CE - 20; - #else - 21; - #endif +static const unsigned kMinDicLogSize = 18; -static const UInt32 kMinDicSize = (1 << kMinDicLogSize); -static const UInt32 kMaxDicSize = +static const UInt32 kMinDicSize = (UInt32)1 << kMinDicLogSize; +static const size_t kMaxDicSize = (size_t)1 << (22 + sizeof(size_t) / 4 * 5); +// static const size_t kMaxDicSize = (size_t)1 << 16; + /* #ifdef MY_CPU_64BIT - (1 << 30); + (UInt32)(Int32)-1; // we can use it, if we want 4 GB buffer + // (UInt32)15 << 28; #else - (1 << 27); + (UInt32)1 << 27; #endif + */ + + +static int ComboBox_Add_UInt32(NWindows::NControl::CComboBox &cb, UInt32 v) +{ + TCHAR s[16]; + ConvertUInt32ToString(v, s); + int index = (int)cb.AddString(s); + cb.SetItemData(index, v); + return index; +} + bool CBenchmarkDialog::OnInit() { #ifdef LANG LangSetWindowText(*this, IDD_BENCH); LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); + // LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); LangSetDlgItemText(*this, IDT_BENCH_CURRENT2, IDT_BENCH_CURRENT); LangSetDlgItemText(*this, IDT_BENCH_RESULTING2, IDT_BENCH_RESULTING); #endif - Sync.Init(); + InitSyncNew(); if (TotalMode) { @@ -120,154 +481,194 @@ bool CBenchmarkDialog::OnInit() UInt32 numCPUs = 1; { - UString s ("/ "); + AString s ("/ "); NSystem::CProcessAffinity threadsInfo; threadsInfo.InitST(); #ifndef _7ZIP_ST - if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0) numCPUs = threadsInfo.GetNumProcessThreads(); else numCPUs = NSystem::GetNumberOfProcessors(); - #endif s.Add_UInt32(numCPUs); s += GetProcessThreadsInfo(threadsInfo); - SetItemText(IDT_BENCH_HARDWARE_THREADS, s); - } - - { - UString s; - { - AString s1, s2; - GetSysInfo(s1, s2); - s = s1; - SetItemText(IDT_BENCH_SYS1, s); - if (s1 != s2 && !s2.IsEmpty()) - { - s = s2; - SetItemText(IDT_BENCH_SYS2, s); - } - } - /* + SetItemTextA(IDT_BENCH_HARDWARE_THREADS, s); + { - GetVersionString(s); - SetItemText(IDT_BENCH_SYSTEM, s); + AString s2; + GetSysInfo(s, s2); + SetItemTextA(IDT_BENCH_SYS1, s); + if (s != s2 && !s2.IsEmpty()) + SetItemTextA(IDT_BENCH_SYS2, s2); } - */ { - AString s2; - GetCpuName(s2); - s = s2; - SetItemText(IDT_BENCH_CPU, s); + GetCpuName_MultiLine(s); + SetItemTextA(IDT_BENCH_CPU, s); } { - AString s2; - AddCpuFeatures(s2); - s = s2; - SetItemText(IDT_BENCH_CPU_FEATURE, s); + GetOsInfoText(s); + s += " : "; + AddCpuFeatures(s); + SetItemTextA(IDT_BENCH_CPU_FEATURE, s); } s = "7-Zip " MY_VERSION_CPU; - SetItemText(IDT_BENCH_VER, s); + SetItemTextA(IDT_BENCH_VER, s); } + // ----- Num Threads ---------- + if (numCPUs < 1) numCPUs = 1; - numCPUs = MyMin(numCPUs, (UInt32)(1 << 8)); + numCPUs = MyMin(numCPUs, (UInt32)(1 << 6)); // it's WIN32 limit + + UInt32 numThreads = Sync.NumThreads; + + if (numThreads == (UInt32)(Int32)-1) + numThreads = numCPUs; + if (numThreads > 1) + numThreads &= ~1; + const UInt32 kNumThreadsMax = (1 << 12); + if (numThreads > kNumThreadsMax) + numThreads = kNumThreadsMax; - if (Sync.NumThreads == (UInt32)(Int32)-1) - { - Sync.NumThreads = numCPUs; - if (Sync.NumThreads > 1) - Sync.NumThreads &= ~1; - } m_NumThreads.Attach(GetItem(IDC_BENCH_NUM_THREADS)); + const UInt32 numTheads_Combo = numCPUs * 2; + UInt32 v = 1; int cur = 0; - for (UInt32 num = 1; num <= numCPUs * 2;) + for (; v <= numTheads_Combo;) { - TCHAR s[16]; - ConvertUInt32ToString(num, s); - int index = (int)m_NumThreads.AddString(s); - m_NumThreads.SetItemData(index, num); - if (num <= Sync.NumThreads) + int index = ComboBox_Add_UInt32(m_NumThreads, v); + const UInt32 vNext = v + (v < 2 ? 1 : 2); + if (v <= numThreads) + if (numThreads < vNext || vNext > numTheads_Combo) + { + if (v != numThreads) + index = ComboBox_Add_UInt32(m_NumThreads, numThreads); cur = index; - if (num > 1) - num++; - num++; + } + v = vNext; } m_NumThreads.SetCurSel(cur); Sync.NumThreads = GetNumberOfThreads(); + + // ----- Dictionary ---------- + m_Dictionary.Attach(GetItem(IDC_BENCH_DICTIONARY)); - cur = 0; - ramSize = (UInt64)(sizeof(size_t)) << 29; - ramSize_Defined = NSystem::GetRamSize(ramSize); + RamSize = (UInt64)(sizeof(size_t)) << 29; + RamSize_Defined = NSystem::GetRamSize(RamSize); + #ifdef UNDER_CE const UInt32 kNormalizedCeSize = (16 << 20); - if (ramSize > kNormalizedCeSize && ramSize < (33 << 20)) - ramSize = kNormalizedCeSize; + if (RamSize > kNormalizedCeSize && RamSize < (33 << 20)) + RamSize = kNormalizedCeSize; #endif + RamSize_Limit = RamSize / 16 * 15; - if (Sync.DictionarySize == (UInt32)(Int32)-1) + if (Sync.DictSize == (UInt64)(Int64)-1) { unsigned dicSizeLog = 25; - #ifdef UNDER_CE dicSizeLog = 20; #endif - - if (ramSize_Defined) + if (RamSize_Defined) for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(Sync.NumThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize) + if (IsMemoryUsageOK(GetBenchMemoryUsage( + Sync.NumThreads, Sync.Level, (UInt64)1 << dicSizeLog, TotalMode))) break; - Sync.DictionarySize = (1 << dicSizeLog); + Sync.DictSize = (UInt64)1 << dicSizeLog; } - if (Sync.DictionarySize < kMinDicSize) Sync.DictionarySize = kMinDicSize; - if (Sync.DictionarySize > kMaxDicSize) Sync.DictionarySize = kMaxDicSize; + if (Sync.DictSize < kMinDicSize) Sync.DictSize = kMinDicSize; + if (Sync.DictSize > kMaxDicSize) Sync.DictSize = kMaxDicSize; - for (unsigned i = kMinDicLogSize; i <= 30; i++) - for (unsigned j = 0; j < 2; j++) - { - UInt32 dict = ((UInt32)1 << i) + ((UInt32)j << (i - 1)); - if (dict > kMaxDicSize) - continue; + cur = 0; + for (unsigned i = (kMinDicLogSize - 1) * 2; i <= (32 - 1) * 2; i++) + { + const size_t dict = (size_t)(2 + (i & 1)) << (i / 2); + // if (i == (32 - 1) * 2) dict = kMaxDicSize; TCHAR s[32]; - ConvertUInt32ToString((dict >> 20), s); - lstrcat(s, kMB); - int index = (int)m_Dictionary.AddString(s); + const TCHAR *post; + UInt32 d; + if (dict >= ((UInt32)1 << 31)) { d = (UInt32)(dict >> 30); post = kGB; } + else if (dict >= ((UInt32)1 << 21)) { d = (UInt32)(dict >> 20); post = kMB; } + else { d = (UInt32)(dict >> 10); post = kKB; } + ConvertUInt32ToString(d, s); + lstrcat(s, post); + const int index = (int)m_Dictionary.AddString(s); m_Dictionary.SetItemData(index, dict); - if (dict <= Sync.DictionarySize) + if (dict <= Sync.DictSize) cur = index; + if (dict >= kMaxDicSize) + break; } m_Dictionary.SetCurSel(cur); - OnChangeSettings(); - Sync._startEvent.Set(); - _timer = SetTimer(kTimerID, kTimerElapse); + // ----- Num Passes ---------- + + m_NumPasses.Attach(GetItem(IDC_BENCH_NUM_PASSES)); + cur = 0; + v = 1; + for (;;) + { + int index = ComboBox_Add_UInt32(m_NumPasses, v); + const bool isLast = (v >= 10000000); + UInt32 vNext = v * 10; + if (v < 2) vNext = 2; + else if (v < 5) vNext = 5; + else if (v < 10) vNext = 10; + + if (v <= Sync.NumPasses_Limit) + if (isLast || Sync.NumPasses_Limit < vNext) + { + if (v != Sync.NumPasses_Limit) + index = ComboBox_Add_UInt32(m_NumPasses, Sync.NumPasses_Limit); + cur = index; + } + v = vNext; + if (isLast) + break; + } + m_NumPasses.SetCurSel(cur); if (TotalMode) NormalizeSize(true); else NormalizePosition(); + + RestartBenchmark(); + return CModalDialog::OnInit(); } + bool CBenchmarkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) { - if (!TotalMode) - return false; int mx, my; GetMargins(8, mx, my); + + if (!TotalMode) + { + RECT rect; + GetClientRectOfItem(IDT_BENCH_LOG, rect); + int x = xSize - rect.left - mx; + int y = ySize - rect.top - my; + if (x < 0) x = 0; + if (y < 0) y = 0; + MoveItem(IDT_BENCH_LOG, rect.left, rect.top, x, y, true); + return false; + } + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); GetItemSizes(IDHELP, bx2, by); @@ -299,12 +700,28 @@ bool CBenchmarkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) return false; } + UInt32 CBenchmarkDialog::GetNumberOfThreads() { return (UInt32)m_NumThreads.GetItemData_of_CurSel(); } +#define UINT_TO_STR_3(s, val) { \ + s[0] = (wchar_t)('0' + (val) / 100); \ + s[1] = (wchar_t)('0' + (val) % 100 / 10); \ + s[2] = (wchar_t)('0' + (val) % 10); \ + s[3] = 0; } + +static void NumberToDot3(UInt64 val, WCHAR *s) +{ + ConvertUInt64ToString(val / 1000, s); + const UInt32 rem = (UInt32)(val % 1000); + s += MyStringLen(s); + *s++ = '.'; + UINT_TO_STR_3(s, rem); +} + void CBenchmarkDialog::SetItemText_Number(int itemID, UInt64 val, LPCTSTR post) { TCHAR s[64]; @@ -314,7 +731,7 @@ void CBenchmarkDialog::SetItemText_Number(int itemID, UInt64 val, LPCTSTR post) SetItemText(itemID, s); } -static void PrintSize_MB(UString &s, UInt64 size) +static void AddSize_MB(UString &s, UInt64 size) { char temp[32]; ConvertUInt64ToString((size + (1 << 20) - 1) >> 20, temp); @@ -322,25 +739,36 @@ static void PrintSize_MB(UString &s, UInt64 size) s += kMB; } - -UInt32 CBenchmarkDialog::OnChangeDictionary() +void CBenchmarkDialog::Print_MemUsage(UString &s, UInt64 memUsage) const { - const UInt32 dict = (UInt32)m_Dictionary.GetItemData_of_CurSel(); - const UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dict); - - UString s; - PrintSize_MB(s, memUsage); - if (ramSize_Defined) + AddSize_MB(s, memUsage); + if (RamSize_Defined) { s += " / "; - PrintSize_MB(s, ramSize); + AddSize_MB(s, RamSize); } +} + +size_t CBenchmarkDialog::OnChangeDictionary() +{ + const size_t dict = (size_t)m_Dictionary.GetItemData_of_CurSel(); + const UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), + Sync.Level, + dict, + false); // totalBench mode + + UString s; + Print_MemUsage(s, memUsage); #ifdef _7ZIP_LARGE_PAGES { AString s2; Add_LargePages_String(s2); - s += s2; + if (!s2.IsEmpty()) + { + s.Add_Space(); + s += s2; + } } #endif @@ -349,8 +777,11 @@ UInt32 CBenchmarkDialog::OnChangeDictionary() return dict; } + static const UInt32 g_IDs[] = { + IDT_BENCH_COMPRESS_SIZE1, + IDT_BENCH_COMPRESS_SIZE2, IDT_BENCH_COMPRESS_USAGE1, IDT_BENCH_COMPRESS_USAGE2, IDT_BENCH_COMPRESS_SPEED1, @@ -360,6 +791,8 @@ static const UInt32 g_IDs[] = IDT_BENCH_COMPRESS_RPU1, IDT_BENCH_COMPRESS_RPU2, + IDT_BENCH_DECOMPR_SIZE1, + IDT_BENCH_DECOMPR_SIZE2, IDT_BENCH_DECOMPR_SPEED1, IDT_BENCH_DECOMPR_SPEED2, IDT_BENCH_DECOMPR_RATING1, @@ -372,108 +805,456 @@ static const UInt32 g_IDs[] = IDT_BENCH_TOTAL_USAGE_VAL, IDT_BENCH_TOTAL_RATING_VAL, IDT_BENCH_TOTAL_RPU_VAL - - // IDT_BENCH_FREQ_CUR, - // IDT_BENCH_FREQ_RES }; -void CBenchmarkDialog::OnChangeSettings() + +static const unsigned k_Ids_Enc_1[] = { + IDT_BENCH_COMPRESS_USAGE1, + IDT_BENCH_COMPRESS_SPEED1, + IDT_BENCH_COMPRESS_RPU1, + IDT_BENCH_COMPRESS_RATING1, + IDT_BENCH_COMPRESS_SIZE1 }; + +static const unsigned k_Ids_Enc[] = { + IDT_BENCH_COMPRESS_USAGE2, + IDT_BENCH_COMPRESS_SPEED2, + IDT_BENCH_COMPRESS_RPU2, + IDT_BENCH_COMPRESS_RATING2, + IDT_BENCH_COMPRESS_SIZE2 }; + +static const unsigned k_Ids_Dec_1[] = { + IDT_BENCH_DECOMPR_USAGE1, + IDT_BENCH_DECOMPR_SPEED1, + IDT_BENCH_DECOMPR_RPU1, + IDT_BENCH_DECOMPR_RATING1, + IDT_BENCH_DECOMPR_SIZE1 }; + +static const unsigned k_Ids_Dec[] = { + IDT_BENCH_DECOMPR_USAGE2, + IDT_BENCH_DECOMPR_SPEED2, + IDT_BENCH_DECOMPR_RPU2, + IDT_BENCH_DECOMPR_RATING2, + IDT_BENCH_DECOMPR_SIZE2 }; + +static const unsigned k_Ids_Tot[] = { + IDT_BENCH_TOTAL_USAGE_VAL, + 0, + IDT_BENCH_TOTAL_RPU_VAL, + IDT_BENCH_TOTAL_RATING_VAL, + 0 }; + + +void CBenchmarkDialog::MyKillTimer() { - EnableItem(IDB_STOP, true); - UInt32 dict = OnChangeDictionary(); + if (_timer != 0) + { + KillTimer(kTimerID); + _timer = 0; + } +} + + +bool CBenchmarkDialog::OnDestroy() +{ + /* actually timer was removed before. + also the timer must be removed by Windows, when window will be removed. */ + MyKillTimer(); // it's optional code + return false; // we return (false) to perform default dialog operation +} + +void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString); + +void CBenchmarkDialog::StartBenchmark() +{ + NeedRestart = false; + WasStopped_in_GUI = false; + + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + MyKillTimer(); // optional code. timer was killed before + + const size_t dict = OnChangeDictionary(); + const UInt32 numThreads = GetNumberOfThreads(); + const UInt32 numPasses = (UInt32)m_NumPasses.GetItemData_of_CurSel(); + for (unsigned i = 0; i < ARRAY_SIZE(g_IDs); i++) SetItemText(g_IDs[i], kProcessingString); + + SetItemText_Empty(IDT_BENCH_LOG); + SetItemText_Empty(IDT_BENCH_ELAPSED_VAL); + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + + const UInt64 memUsage = GetBenchMemoryUsage(numThreads, Sync.Level, dict, + false); // totalBench + if (!IsMemoryUsageOK(memUsage)) + { + UString s2 = LangString(IDT_BENCH_MEMORY); + if (s2.IsEmpty()) + GetItemText(IDT_BENCH_MEMORY, s2); + UString s; + SetErrorMessage_MemUsage(s, memUsage, RamSize, RamSize_Limit, s2); + MessageBoxError_Status(s); + return; + } + + EnableItem(IDB_STOP, true); + _startTime = GetTickCount(); + _finishTime = _startTime; + _finishTime_WasSet = false; + + { + NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); + InitSyncNew(); + Sync.DictSize = dict; + Sync.NumThreads = numThreads; + Sync.NumPasses_Limit = numPasses; + } + PrintTime(); - NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); - Sync.Init(); - Sync.DictionarySize = dict; - Sync.Changed = true; - Sync.NumThreads = GetNumberOfThreads(); + + _timer = SetTimer(kTimerID, kTimerElapse); + if (_thread.Create(CThreadBenchmark::MyThreadFunction, &_threadBenchmark) != 0) + { + MyKillTimer(); + MessageBoxError_Status(L"Can't create thread"); + }; + return; } -void CBenchmarkDialog::OnRestartButton() + +void CBenchmarkDialog::RestartBenchmark() { - OnChangeSettings(); + if (ExitWasAsked_in_GUI) + return; + + if (_thread.IsCreated()) + { + NeedRestart = true; + SendExit_Status(L"Stop for restart ..."); + } + else + StartBenchmark(); } -void CBenchmarkDialog::OnStopButton() + +void CBenchmarkDialog::Disable_Stop_Button() { + // if we disable focused button, then focus will be lost + if (GetFocus() == GetItem(IDB_STOP)) + { + // SendMsg_NextDlgCtl_Prev(); + SendMsg_NextDlgCtl_CtlId(IDB_RESTART); + } EnableItem(IDB_STOP, false); - Sync.Pause(); } -void CBenchmarkDialog::OnHelp() + +void CBenchmarkDialog::OnStopButton() { - ShowHelpWindow(kHelpTopic); + if (ExitWasAsked_in_GUI) + return; + + Disable_Stop_Button(); + + WasStopped_in_GUI = true; + if (_thread.IsCreated()) + { + SendExit_Status(L"Stop ..."); + } } + + void CBenchmarkDialog::OnCancel() { - Sync.Stop(); - KillTimer(_timer); - CModalDialog::OnCancel(); + ExitWasAsked_in_GUI = true; + + /* + SendMsg_NextDlgCtl_Prev(); + EnableItem(IDCANCEL, false); + */ + + if (_thread.IsCreated()) + SendExit_Status(L"Cancel ..."); + else + CModalDialog::OnCancel(); } -void GetTimeString(UInt64 timeValue, wchar_t *s); + +void CBenchmarkDialog::OnHelp() +{ + ShowHelpWindow(kHelpTopic); +} + + + +// void GetTimeString(UInt64 timeValue, wchar_t *s); void CBenchmarkDialog::PrintTime() { - UInt32 curTime = ::GetTickCount(); - UInt32 elapsedTime = (curTime - _startTime); - UInt32 elapsedSec = elapsedTime / 1000; - if (elapsedSec != 0 && Sync.WasPaused()) + const UInt32 curTime = + _finishTime_WasSet ? + _finishTime : + ::GetTickCount(); + + const UInt32 elapsedTime = (curTime - _startTime); + + WCHAR s[64]; + + // GetTimeString(elapsedTime / 1000, s); + ConvertUInt32ToString(elapsedTime / 1000, s); + + if (_finishTime_WasSet) + { + WCHAR *p = s + MyStringLen(s); + *p++ = '.'; + UINT_TO_STR_3(p, elapsedTime % 1000); + } + + // NumberToDot3((UInt64)elapsedTime, s); + + wcscat(s, L" s"); + + // if (WasStopped_in_GUI) wcscat(s, L" X"); // for debug + + if (s == ElapsedSec_Prev) return; - WCHAR s[40]; - GetTimeString(elapsedSec, s); + + ElapsedSec_Prev = s; + + // static cnt = 0; cnt++; wcscat(s, L" "); + // UString s2; s2.Add_UInt32(cnt); wcscat(s, s2.Ptr()); + SetItemText(IDT_BENCH_ELAPSED_VAL, s); } + +static UInt64 GetMips(UInt64 ips) +{ + return (ips + 500000) / 1000000; +} + + +static UInt64 GetUsagePercents(UInt64 usage) +{ + return Benchmark_GetUsage_Percents(usage); +} + + +static UInt32 GetRating(const CTotalBenchRes &info) +{ + UInt64 numIter = info.NumIterations2; + if (numIter == 0) + numIter = 1000000; + const UInt64 rating64 = GetMips(info.Rating / numIter); + // return rating64; + UInt32 rating32 = (UInt32)rating64; + if (rating32 != rating64) + rating32 = (UInt32)(Int32)-1; + return rating32; +}; + + +static void AddUsageString(UString &s, const CTotalBenchRes &info) +{ + UInt64 numIter = info.NumIterations2; + if (numIter == 0) + numIter = 1000000; + UInt64 usage = GetUsagePercents(info.Usage / numIter); + + wchar_t w[64]; + ConvertUInt64ToString(usage, w); + unsigned len = MyStringLen(w); + while (len < 5) + { + s.Add_Space(); + len++; + } + s += w; + s += "%"; +} + + +static void Add_Dot3String(UString &s, UInt64 val) +{ + WCHAR temp[32]; + NumberToDot3(val, temp); + s += temp; +} + + +static void AddRatingString(UString &s, const CTotalBenchRes &info) +{ + // AddUsageString(s, info); + // s += " "; + // s.Add_UInt32(GetRating(info)); + Add_Dot3String(s, GetRating(info)); +}; + + +static void AddRatingsLine(UString &s, const CTotalBenchRes &enc, const CTotalBenchRes &dec + #ifdef PRINT_ITER_TIME + , DWORD ticks + #endif + ) +{ + // AddUsageString(s, enc); s += " "; + + AddRatingString(s, enc); + s += " "; + AddRatingString(s, dec); + + CTotalBenchRes tot_BenchRes; + tot_BenchRes.SetSum(enc, dec); + + s += " "; + AddRatingString(s, tot_BenchRes); + + s += " "; AddUsageString(s, tot_BenchRes); + + + #ifdef PRINT_ITER_TIME + s += " "; + { + Add_Dot3String(s, ticks; + s += " s"; + // s.Add_UInt32(ticks); s += " ms"; + } + #endif +} + + void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) { - SetItemText_Number(controlID, rating / 1000000, kMIPS); + // SetItemText_Number(controlID, GetMips(rating), kMIPS); + WCHAR s[64]; + NumberToDot3(GetMips(rating), s); + MyStringCat(s, L" GIPS"); + SetItemText(controlID, s); } void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID) { - SetItemText_Number(controlID, (usage + 5000) / 10000, TEXT("%")); + SetItemText_Number(controlID, GetUsagePercents(usage), TEXT("%")); } -void CBenchmarkDialog::PrintResults( - UInt32 dictionarySize, - const CBenchInfo2 &info, - UINT usageID, UINT speedID, UINT rpuID, UINT ratingID, - bool decompressMode) + +// void SetItemText_Number + +void CBenchmarkDialog::PrintBenchRes( + const CTotalBenchRes2 &info, + const UINT ids[]) { - if (info.GlobalTime == 0) + if (info.NumIterations2 == 0) return; - + if (ids[1] != 0) + SetItemText_Number(ids[1], (info.Speed >> 10) / info.NumIterations2, kKBs); + PrintRating(info.Rating / info.NumIterations2, ids[3]); + PrintRating(info.RPU / info.NumIterations2, ids[2]); + PrintUsage(info.Usage / info.NumIterations2, ids[0]); + if (ids[4] != 0) { - const UInt64 speed = info.UnpackSize * info.NumIterations * info.GlobalFreq / info.GlobalTime; - SetItemText_Number(speedID, speed >> 10, kKBs); + UInt64 val = info.UnpackSize; + LPCTSTR kPostfix; + if (val >= ((UInt64)1 << 40)) + { + kPostfix = kGB; + val >>= 30; + } + else + { + kPostfix = kMB; + val >>= 20; + } + SetItemText_Number(ids[4], val, kPostfix); } - UInt64 rating; - if (decompressMode) - rating = info.GetDecompressRating(); - else - rating = info.GetCompressRating(dictionarySize); - - PrintRating(rating, ratingID); - PrintRating(info.GetRatingPerUsage(rating), rpuID); - PrintUsage(info.GetUsage(), usageID); } -bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) + +// static UInt32 k_Message_Finished_cnt = 0; +// static UInt32 k_OnTimer_cnt = 0; + +bool CBenchmarkDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { - bool printTime = true; - if (TotalMode) + if (message != k_Message_Finished) + return CModalDialog::OnMessage(message, wParam, lParam); + { - if (Sync.WasStopped()) - printTime = false; + if (wParam == k_Msg_WPARM_Thread_Finished) + { + _finishTime = GetTickCount(); + _finishTime_WasSet = true; + MyKillTimer(); + + if (_thread.Wait_Close() != 0) + { + MessageBoxError_Status(L"Thread Wait Error"); + } + + if (!WasStopped_in_GUI) + { + WasStopped_in_GUI = true; + Disable_Stop_Button(); + } + + HRESULT res = Sync.BenchFinish_Thread_HRESULT; + if (res != S_OK) + // if (!ExitWasAsked_in_GUI || res != E_ABORT) + MessageBoxError_Status(HResultToMessage(res)); + + if (ExitWasAsked_in_GUI) + { + // SetItemText(IDT_BENCH_ERROR_MESSAGE, "before CModalDialog::OnCancel()"); + // Sleep (2000); + // MessageBoxError(L"test"); + CModalDialog::OnCancel(); + return true; + } + + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + + res = Sync.BenchFinish_Task_HRESULT; + if (res != S_OK) + { + if (!WasStopped_in_GUI || res != E_ABORT) + { + UString m; + if (res == S_FALSE) + m = "Decoding error"; + else if (res == CLASS_E_CLASSNOTAVAILABLE) + m = "Can't find 7z.dll"; + else + m = HResultToMessage(res); + MessageBoxError_Status(m); + } + } + + if (NeedRestart) + { + StartBenchmark(); + return true; + } + } + // k_Message_Finished_cnt++; + UpdateGui(); + return true; } - if (printTime) - PrintTime(); +} + + +bool CBenchmarkDialog::OnTimer(WPARAM timerID, LPARAM /* callback */) +{ + // k_OnTimer_cnt++; + if (timerID == kTimerID) + UpdateGui(); + return true; +} + + +void CBenchmarkDialog::UpdateGui() +{ + PrintTime(); if (TotalMode) { @@ -491,103 +1272,147 @@ bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) } if (wasChanged) _consoleEdit.SetText(Bench2Text); - return true; + return; } - SetItemText_Number(IDT_BENCH_SIZE_VAL, (Sync.ProcessedSize >> 20), kMB); + CSyncData sd; + CRecordVector<CBenchPassResult> RatingVector; - SetItemText_Number(IDT_BENCH_PASSES_VAL, Sync.NumPasses); + { + NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); + sd = Sync.sd; - /* - if (Sync.FirstPath) - SetItemText_Number(IDT_BENCH_FREQ_CUR, Sync.Freq, TEXT(" MHz")); - else - SetItemText_Number(IDT_BENCH_FREQ_RES, Sync.Freq, TEXT(" MHz")); - */ + if (sd.NeedPrint_RatingVector) + RatingVector = Sync.RatingVector; + + if (sd.NeedPrint_Freq) + { + Sync.FreqString_GUI = Sync.FreqString_Sync; + sd.NeedPrint_RatingVector = true; + } - /* - if (Sync.FreqWasChanged) - { - SetItemText(IDT_BENCH_FREQ, Sync.Freq); - Sync.FreqWasChanged = false; + Sync.sd.NeedPrint_RatingVector = false; + Sync.sd.NeedPrint_Enc_1 = false; + Sync.sd.NeedPrint_Enc = false; + Sync.sd.NeedPrint_Dec_1 = false; + Sync.sd.NeedPrint_Dec = false; + Sync.sd.NeedPrint_Tot = false; + Sync.sd.NeedPrint_Freq = false; } - */ + if (sd.NumPasses_Finished != NumPasses_Finished_Prev) { - UInt32 dicSizeTemp = (UInt32)MyMax(Sync.ProcessedSize, UInt64(1) << 20); - dicSizeTemp = MyMin(dicSizeTemp, Sync.DictionarySize); - PrintResults(dicSizeTemp, - Sync.CompressingInfoTemp, - IDT_BENCH_COMPRESS_USAGE1, - IDT_BENCH_COMPRESS_SPEED1, - IDT_BENCH_COMPRESS_RPU1, - IDT_BENCH_COMPRESS_RATING1); + SetItemText_Number(IDT_BENCH_PASSES_VAL, sd.NumPasses_Finished, TEXT(" /")); + NumPasses_Finished_Prev = sd.NumPasses_Finished; } + if (sd.NeedPrint_Enc_1) PrintBenchRes(sd.Enc_BenchRes_1, k_Ids_Enc_1); + if (sd.NeedPrint_Enc) PrintBenchRes(sd.Enc_BenchRes, k_Ids_Enc); + if (sd.NeedPrint_Dec_1) PrintBenchRes(sd.Dec_BenchRes_1, k_Ids_Dec_1); + if (sd.NeedPrint_Dec) PrintBenchRes(sd.Dec_BenchRes, k_Ids_Dec); + + if (sd.BenchWasFinished && sd.NeedPrint_Tot) { - PrintResults( - Sync.DictionarySize, - Sync.CompressingInfo, - IDT_BENCH_COMPRESS_USAGE2, - IDT_BENCH_COMPRESS_SPEED2, - IDT_BENCH_COMPRESS_RPU2, - IDT_BENCH_COMPRESS_RATING2); + CTotalBenchRes2 tot_BenchRes = sd.Enc_BenchRes; + tot_BenchRes.Update_With_Res2(sd.Dec_BenchRes); + PrintBenchRes(tot_BenchRes, k_Ids_Tot); } + + if (sd.NeedPrint_RatingVector) + // for (unsigned k = 0; k < 1; k++) { - PrintResults( - Sync.DictionarySize, - Sync.DecompressingInfoTemp, - IDT_BENCH_DECOMPR_USAGE1, - IDT_BENCH_DECOMPR_SPEED1, - IDT_BENCH_DECOMPR_RPU1, - IDT_BENCH_DECOMPR_RATING1, - true); - } - { - PrintResults( - Sync.DictionarySize, - Sync.DecompressingInfo, - IDT_BENCH_DECOMPR_USAGE2, - IDT_BENCH_DECOMPR_SPEED2, - IDT_BENCH_DECOMPR_RPU2, - IDT_BENCH_DECOMPR_RATING2, - true); - if (Sync.DecompressingInfo.GlobalTime > 0 && - Sync.CompressingInfo.GlobalTime > 0) + UString s; + s += Sync.FreqString_GUI; + if (!RatingVector.IsEmpty()) + { + if (!s.IsEmpty()) + s.Add_LF(); + s += "Compr Decompr Total CPU" + #ifdef PRINT_ITER_TIME + " Time" + #endif + ; + s.Add_LF(); + } + // s += "GIPS GIPS GIPS % s"; s.Add_LF(); + for (unsigned i = 0; i < RatingVector.Size(); i++) + { + if (i != 0) + s.Add_LF(); + if ((int)i == sd.RatingVector_DeletedIndex) + { + s += "..."; + s.Add_LF(); + } + const CBenchPassResult &pair = RatingVector[i]; + /* + s += "g:"; s.Add_UInt32((UInt32)pair.EncInfo.GlobalTime); + s += " u:"; s.Add_UInt32((UInt32)pair.EncInfo.UserTime); + s += " "; + */ + AddRatingsLine(s, pair.Enc, pair.Dec + #ifdef PRINT_ITER_TIME + , pair.Ticks + #endif + ); + /* + { + UInt64 v = i + 1; + if (sd.RatingVector_DeletedIndex >= 0 && i >= (unsigned)sd.RatingVector_DeletedIndex) + v += sd.RatingVector_NumDeleted; + char temp[64]; + ConvertUInt64ToString(v, temp); + s += " : "; + s += temp; + } + */ + } + + if (sd.BenchWasFinished) { - UInt64 comprRating = Sync.CompressingInfo.GetCompressRating(Sync.DictionarySize); - UInt64 decomprRating = Sync.DecompressingInfo.GetDecompressRating(); - PrintRating((comprRating + decomprRating) / 2, IDT_BENCH_TOTAL_RATING_VAL); - PrintRating(( - Sync.CompressingInfo.GetRatingPerUsage(comprRating) + - Sync.DecompressingInfo.GetRatingPerUsage(decomprRating)) / 2, IDT_BENCH_TOTAL_RPU_VAL); - PrintUsage( - (Sync.CompressingInfo.GetUsage() + - Sync.DecompressingInfo.GetUsage()) / 2, IDT_BENCH_TOTAL_USAGE_VAL); + s.Add_LF(); + s += "-------------"; + s.Add_LF(); + { + // average time is not correct because of freq detection in first iteration + AddRatingsLine(s, sd.Enc_BenchRes, sd.Dec_BenchRes + #ifdef PRINT_ITER_TIME + , (DWORD)(sd.TotalTicks / (sd.NumPasses_Finished ? sd.NumPasses_Finished : 1)) + #endif + ); + } } + // s.Add_LF(); s += "OnTimer: "; s.Add_UInt32(k_OnTimer_cnt); + // s.Add_LF(); s += "finished Message: "; s.Add_UInt32(k_Message_Finished_cnt); + // static cnt = 0; cnt++; s.Add_LF(); s += "Print: "; s.Add_UInt32(cnt); + // s.Add_LF(); s += "NumEncProgress: "; s.Add_UInt32((UInt32)sd.NumEncProgress); + // s.Add_LF(); s += "NumDecProgress: "; s.Add_UInt32((UInt32)sd.NumDecProgress); + SetItemText(IDT_BENCH_LOG, s); } - return true; } + bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam) { if (code == CBN_SELCHANGE && (itemID == IDC_BENCH_DICTIONARY || + itemID == IDC_BENCH_NUM_PASSES || itemID == IDC_BENCH_NUM_THREADS)) { - OnChangeSettings(); + RestartBenchmark(); return true; } return CModalDialog::OnCommand(code, itemID, lParam); } + bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { switch (buttonID) { case IDB_RESTART: - OnRestartButton(); + RestartBenchmark(); return true; case IDB_STOP: OnStopButton(); @@ -596,87 +1421,81 @@ bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) return CModalDialog::OnButtonClicked(buttonID, buttonHWND); } -struct CThreadBenchmark -{ - CBenchmarkDialog *BenchmarkDialog; - DECL_EXTERNAL_CODECS_LOC_VARS2; - // UInt32 dictionarySize; - // UInt32 numThreads; - HRESULT Process(); - HRESULT Result; - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process(); - return 0; - } -}; + + + +// ---------- Benchmark Thread ---------- struct CBenchCallback: public IBenchCallback { - UInt32 dictionarySize; + UInt64 dictionarySize; CBenchProgressSync *Sync; + CBenchmarkDialog *BenchmarkDialog; - // void AddCpuFreq(UInt64 cpuFreq); - HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); HRESULT SetEncodeResult(const CBenchInfo &info, bool final); HRESULT SetDecodeResult(const CBenchInfo &info, bool final); }; -/* -void CBenchCallback::AddCpuFreq(UInt64 cpuFreq) -{ - NSynchronization::CCriticalSectionLock lock(Sync->CS); - { - wchar_t s[32]; - ConvertUInt64ToString(cpuFreq, s); - Sync->Freq.Add_Space_if_NotEmpty(); - Sync->Freq += s; - Sync->FreqWasChanged = true; - } -} -*/ - -HRESULT CBenchCallback::SetFreq(bool /* showFreq */, UInt64 /* cpuFreq */) -{ - return S_OK; -} - HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final) { - NSynchronization::CCriticalSectionLock lock(Sync->CS); - if (Sync->Changed || Sync->Paused || Sync->Stopped) - return E_ABORT; - Sync->ProcessedSize = info.UnpackSize * info.NumIterations; - if (final && Sync->CompressingInfo.GlobalTime == 0) + bool needPost = false; { - (CBenchInfo&)Sync->CompressingInfo = info; - if (Sync->CompressingInfo.GlobalTime == 0) - Sync->CompressingInfo.GlobalTime = 1; + NSynchronization::CCriticalSectionLock lock(Sync->CS); + if (Sync->Exit) + return E_ABORT; + CSyncData &sd = Sync->sd; + // sd.NumEncProgress++; + CTotalBenchRes2 &br = sd.Enc_BenchRes_1; + { + UInt64 dictSize = Sync->DictSize; + if (final) + { + // sd.EncInfo = info; + } + else + { + /* if (!final), then CBenchInfo::NumIterations means totalNumber of threads. + so we can reduce the dictionary */ + if (dictSize > info.UnpackSize) + dictSize = info.UnpackSize; + } + br.Rating = info.GetRating_LzmaEnc(dictSize); + } + br.SetFrom_BenchInfo(info); + sd.NeedPrint_Enc_1 = true; + if (final) + { + sd.Enc_BenchRes.Update_With_Res2(br); + sd.NeedPrint_Enc = true; + needPost = true; + } } - else - (CBenchInfo&)Sync->CompressingInfoTemp = info; + + if (needPost) + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); return S_OK; } + HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final) { NSynchronization::CCriticalSectionLock lock(Sync->CS); - if (Sync->Changed || Sync->Paused || Sync->Stopped) + if (Sync->Exit) return E_ABORT; - CBenchInfo info2 = info; - if (final && Sync->DecompressingInfo.GlobalTime == 0) - { - (CBenchInfo&)Sync->DecompressingInfo = info2; - if (Sync->DecompressingInfo.GlobalTime == 0) - Sync->DecompressingInfo.GlobalTime = 1; - } - else - (CBenchInfo&)Sync->DecompressingInfoTemp = info2; + CSyncData &sd = Sync->sd; + // sd.NumDecProgress++; + CTotalBenchRes2 &br = sd.Dec_BenchRes_1; + br.Rating = info.GetRating_LzmaDec(); + br.SetFrom_BenchInfo(info); + sd.NeedPrint_Dec_1 = true; + if (final) + sd.Dec_BenchRes.Update_With_Res2(br); return S_OK; } + struct CBenchCallback2: public IBenchPrintCallback { CBenchProgressSync *Sync; @@ -704,74 +1523,145 @@ void CBenchCallback2::NewLine() HRESULT CBenchCallback2::CheckBreak() { - if (Sync->Changed || Sync->Paused || Sync->Stopped) + if (Sync->Exit) return E_ABORT; return S_OK; } -/* struct CFreqCallback: public IBenchFreqCallback { - CBenchProgressSync *Sync; + CBenchmarkDialog *BenchmarkDialog; - virtual void AddCpuFreq(UInt64 freq); + virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage); + virtual HRESULT FreqsFinished(unsigned numThreads); }; -void CFreqCallback::AddCpuFreq(UInt64 freq) +HRESULT CFreqCallback::AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) { - NSynchronization::CCriticalSectionLock lock(Sync->CS); - Sync->Freq = freq; + HRESULT res; + { + CBenchProgressSync &sync = BenchmarkDialog->Sync; + NSynchronization::CCriticalSectionLock lock(sync.CS); + UString &s = sync.FreqString_Sync; + if (sync.NumFreqThreadsPrev != numThreads) + { + sync.NumFreqThreadsPrev = numThreads; + if (!s.IsEmpty()) + s.Add_LF(); + s.Add_UInt32(numThreads); + s += "T Frequency (MHz):"; + s.Add_LF(); + } + s += " "; + char temp[64]; + if (numThreads != 1) + { + ConvertUInt64ToString(GetUsagePercents(usage), temp); + s += temp; + s += '%'; + s.Add_Space(); + } + ConvertUInt64ToString(GetMips(freq), temp); + s += temp; + // BenchmarkDialog->Sync.sd.NeedPrint_Freq = true; + res = sync.Exit ? E_ABORT : S_OK; + } + // BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + return res; +} + +HRESULT CFreqCallback::FreqsFinished(unsigned /* numThreads */) +{ + HRESULT res; + { + CBenchProgressSync &sync = BenchmarkDialog->Sync; + NSynchronization::CCriticalSectionLock lock(sync.CS); + sync.sd.NeedPrint_Freq = true; + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + res = sync.Exit ? E_ABORT : S_OK; + } + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + return res; } -*/ +// define USE_DUMMY only for debug +// #define USE_DUMMY +#ifdef USE_DUMMY +static unsigned dummy = 1; +static unsigned Dummy(unsigned limit) +{ + unsigned sum = 0; + for (unsigned k = 0; k < limit; k++) + { + sum += dummy; + if (sum == 0) + break; + } + return sum; +} +#endif + + HRESULT CThreadBenchmark::Process() { + /* the first benchmark pass can be slow, + if we run benchmark while the window is being created, + and (no freq detecion loop) && (dictionary is small) (-mtic is small) */ + + // Sleep(300); // for debug + #ifdef USE_DUMMY + Dummy(1000 * 1000 * 1000); // for debug + #endif + CBenchProgressSync &sync = BenchmarkDialog->Sync; - sync.WaitCreating(); + HRESULT finishHRESULT = S_OK; + try { - for (;;) + for (UInt32 passIndex = 0;; passIndex++) { - if (sync.WasStopped()) - return 0; - if (sync.WasPaused()) - { - Sleep(200); - continue; - } - UInt32 dictionarySize; + // throw 1; // to debug + // throw CSystemException(E_INVALIDARG); // to debug + + UInt64 dictionarySize; UInt32 numThreads; { NSynchronization::CCriticalSectionLock lock(sync.CS); - if (sync.Stopped || sync.Paused) - continue; - if (sync.Changed) - sync.Init(); - dictionarySize = sync.DictionarySize; + if (sync.Exit) + break; + dictionarySize = sync.DictSize; numThreads = sync.NumThreads; - /* - if (sync.CompressingInfo.GlobalTime != 0) - sync.FirstPath = false; - */ } + + #ifdef PRINT_ITER_TIME + const DWORD startTick = GetTickCount(); + #endif CBenchCallback callback; + callback.dictionarySize = dictionarySize; callback.Sync = &sync; + callback.BenchmarkDialog = BenchmarkDialog; + CBenchCallback2 callback2; callback2.TotalMode = BenchmarkDialog->TotalMode; callback2.Sync = &sync; - // CFreqCallback freqCallback; - // freqCallback.Sync = &sync; + + CFreqCallback freqCallback; + freqCallback.BenchmarkDialog = BenchmarkDialog; + HRESULT result; try { CObjectVector<CProperty> props; + + props = BenchmarkDialog->Props; + if (BenchmarkDialog->TotalMode) { props = BenchmarkDialog->Props; @@ -787,8 +1677,8 @@ HRESULT CThreadBenchmark::Process() { CProperty prop; prop.Name = 'd'; - prop.Name.Add_UInt32(dictionarySize); - prop.Name += 'b'; + prop.Name.Add_UInt32((UInt32)(dictionarySize >> 10)); + prop.Name += 'k'; props.Add(prop); } } @@ -796,57 +1686,133 @@ HRESULT CThreadBenchmark::Process() result = Bench(EXTERNAL_CODECS_LOC_VARS BenchmarkDialog->TotalMode ? &callback2 : NULL, BenchmarkDialog->TotalMode ? NULL : &callback, - // &freqCallback, - props, 1, false); + props, 1, false, + (!BenchmarkDialog->TotalMode) && passIndex == 0 ? &freqCallback: NULL); - if (BenchmarkDialog->TotalMode) - { - sync.Stop(); - } + // result = S_FALSE; // for debug; + // throw 1; } catch(...) { result = E_FAIL; } + #ifdef PRINT_ITER_TIME + const DWORD numTicks = GetTickCount() - startTick; + #endif + + bool finished = true; + + NSynchronization::CCriticalSectionLock lock(sync.CS); + if (result != S_OK) { - if (result != E_ABORT) + sync.BenchFinish_Task_HRESULT = result; + break; + } + + { + CSyncData &sd = sync.sd; + + sd.NumPasses_Finished++; + #ifdef PRINT_ITER_TIME + sd.TotalTicks += numTicks; + #endif + + if (BenchmarkDialog->TotalMode) + break; + { + CTotalBenchRes tot_BenchRes = sd.Enc_BenchRes_1; + tot_BenchRes.Update_With_Res(sd.Dec_BenchRes_1); + + sd.NeedPrint_RatingVector = true; { - NSynchronization::CCriticalSectionLock lock(sync.CS); - sync.Pause(); + CBenchPassResult pair; + // pair.EncInfo = sd.EncInfo; // for debug + pair.Enc = sd.Enc_BenchRes_1; + pair.Dec = sd.Dec_BenchRes_1; + #ifdef PRINT_ITER_TIME + pair.Ticks = numTicks; + #endif + sync.RatingVector.Add(pair); + // pair.Dec_Defined = true; } - UString message; - if (result == S_FALSE) - message = "Decoding error"; - else if (result == CLASS_E_CLASSNOTAVAILABLE) - message = "Can't find 7z.dll"; - else - message = HResultToMessage(result); - BenchmarkDialog->MessageBoxError(message); + } + + sd.NeedPrint_Dec = true; + sd.NeedPrint_Tot = true; + + if (sync.RatingVector.Size() > kRatingVector_NumBundlesMax) + { + // sd.RatingVector_NumDeleted++; + sd.RatingVector_DeletedIndex = (int)(kRatingVector_NumBundlesMax / 4); + sync.RatingVector.Delete((unsigned)(sd.RatingVector_DeletedIndex)); + } + + if (sync.sd.NumPasses_Finished < sync.NumPasses_Limit) + finished = false; + else + { + sync.sd.BenchWasFinished = true; + // BenchmarkDialog->_finishTime = GetTickCount(); + // return 0; } } - else + + if (BenchmarkDialog->TotalMode) + break; + + /* + if (newTick - prevTick < 1000) + numSameTick++; + if (numSameTick > 5 || finished) { - NSynchronization::CCriticalSectionLock lock(sync.CS); - sync.NumPasses++; + prevTick = newTick; + numSameTick = 0; + */ + // for (unsigned i = 0; i < 1; i++) + { + // we suppose that PostMsg messages will be processed in order. + if (!BenchmarkDialog->PostMsg_Finish(k_Msg_WPARM_Iter_Finished)) + { + finished = true; + finishHRESULT = E_FAIL; + // throw 1234567; + } } + if (finished) + break; } // return S_OK; } catch(CSystemException &e) { - BenchmarkDialog->MessageBoxError(HResultToMessage(e.ErrorCode)); - return E_FAIL; + finishHRESULT = e.ErrorCode; + // BenchmarkDialog->MessageBoxError(HResultToMessage(e.ErrorCode)); + // return E_FAIL; } catch(...) { - BenchmarkDialog->MessageBoxError(HResultToMessage(E_FAIL)); - return E_FAIL; + finishHRESULT = E_FAIL; + // BenchmarkDialog->MessageBoxError(HResultToMessage(E_FAIL)); + // return E_FAIL; + } + + if (finishHRESULT != S_OK) + { + NSynchronization::CCriticalSectionLock lock(sync.CS); + sync.BenchFinish_Thread_HRESULT = finishHRESULT; } + if (!BenchmarkDialog->PostMsg_Finish(k_Msg_WPARM_Thread_Finished)) + { + // sync.BenchFinish_Thread_HRESULT = E_FAIL; + } + return 0; } + + static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) { const wchar_t *end; @@ -859,20 +1825,21 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) prop = result; } + HRESULT Benchmark( DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector<CProperty> &props, HWND hwndParent) + const CObjectVector<CProperty> &props, UInt32 numIterations, HWND hwndParent) { - CThreadBenchmark benchmarker; - #ifdef EXTERNAL_CODECS - benchmarker.__externalCodecs = __externalCodecs; - #endif - CBenchmarkDialog bd; - bd.Props = props; + bd.TotalMode = false; - bd.Sync.DictionarySize = (UInt32)(Int32)-1; + bd.Props = props; + if (numIterations == 0) + numIterations = 1; + bd.Sync.NumPasses_Limit = numIterations; + bd.Sync.DictSize = (UInt64)(Int64)-1; bd.Sync.NumThreads = (UInt32)(Int32)-1; + bd.Sync.Level = -1; COneMethodInfo method; @@ -905,13 +1872,17 @@ HRESULT Benchmark( #endif continue; } - if (name.IsEqualTo("testtime")) + /* + if (name.IsEqualTo("time")) { // UInt32 testTime = 4; // RINOK(ParsePropToUInt32(L"", propVariant, testTime)); continue; } RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); + */ + // here we need to parse DictSize property, and ignore unknown properties + method.ParseMethodFromPROPVARIANT(name, propVariant); } if (bd.TotalMode) @@ -923,17 +1894,37 @@ HRESULT Benchmark( } { - UInt32 dict; + UInt64 dict; if (method.Get_DicSize(dict)) - bd.Sync.DictionarySize = dict; + bd.Sync.DictSize = dict; + } + bd.Sync.Level = method.GetLevel(); + + // Dummy(1000 * 1000 * 1); + + { + CThreadBenchmark &benchmarker = bd._threadBenchmark; + #ifdef EXTERNAL_CODECS + benchmarker.__externalCodecs = __externalCodecs; + #endif + benchmarker.BenchmarkDialog = &bd; } - benchmarker.BenchmarkDialog = &bd; + bd.Create(hwndParent); + return S_OK; +} + + +CBenchmarkDialog::~CBenchmarkDialog() +{ + if (_thread.IsCreated()) { - NWindows::CThread thread; - RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker)); - bd.Create(hwndParent); - return thread.Wait_Close(); + /* the following code will be not executed in normal code flow. + it can be called, if there is some internal failure in dialog code. */ + Attach(NULL); + MessageBoxError(L"The flaw in benchmark thread code"); + Sync.SendExit(); + _thread.Wait_Close(); } } diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.h b/CPP/7zip/UI/GUI/BenchmarkDialog.h index 1bad8ea9..a280592e 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.h +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.h @@ -3,190 +3,13 @@ #ifndef __BENCHMARK_DIALOG_H #define __BENCHMARK_DIALOG_H -#include "../../../Windows/Synchronization.h" +#include "../../Common/CreateCoder.h" +#include "../../UI/Common/Property.h" -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Edit.h" - -#include "../Common/Bench.h" - -#include "../FileManager/DialogSize.h" - -#include "BenchmarkDialogRes.h" - -struct CBenchInfo2 : public CBenchInfo -{ - void Init() { GlobalTime = UserTime = 0; } - - UInt64 GetCompressRating(UInt32 dictSize) const - { - return ::GetCompressRating(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); - } - - UInt64 GetDecompressRating() const - { - return ::GetDecompressRating(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); - } -}; - -class CBenchProgressSync -{ -public: - bool Stopped; - bool Paused; - bool Changed; - UInt32 DictionarySize; - UInt32 NumThreads; - UInt64 NumPasses; - NWindows::NSynchronization::CManualResetEvent _startEvent; - NWindows::NSynchronization::CCriticalSection CS; - - CBenchInfo2 CompressingInfoTemp; - CBenchInfo2 CompressingInfo; - UInt64 ProcessedSize; - - CBenchInfo2 DecompressingInfoTemp; - CBenchInfo2 DecompressingInfo; - - AString Text; - bool TextWasChanged; - - // bool FirstPath; - // UInt64 Freq; - // UString Freq; - // bool FreqWasChanged; - - CBenchProgressSync() - { - if (_startEvent.Create() != S_OK) - throw 3986437; - } - - void Init() - { - Changed = false; - Stopped = false; - Paused = false; - CompressingInfoTemp.Init(); - CompressingInfo.Init(); - ProcessedSize = 0; - - DecompressingInfoTemp.Init(); - DecompressingInfo.Init(); - - NumPasses = 0; - - // FirstPath = true; - // Freq = 0; - // Freq.SetFromAscii("MHz: "); - // FreqWasChanged = true; - - Text.Empty(); - TextWasChanged = true; - } - - void Stop() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Stopped = true; - } - bool WasStopped() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - return Stopped; - } - void Pause() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Paused = true; - } - void Start() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Paused = false; - } - bool WasPaused() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - return Paused; - } - void WaitCreating() { _startEvent.Lock(); } -}; - -struct CMyFont -{ - HFONT _font; - CMyFont(): _font(NULL) {} - ~CMyFont() - { - if (_font) - DeleteObject(_font); - } - void Create(const LOGFONT *lplf) - { - _font = CreateFontIndirect(lplf); - } -}; - - -class CBenchmarkDialog: - public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox m_Dictionary; - NWindows::NControl::CComboBox m_NumThreads; - NWindows::NControl::CEdit _consoleEdit; - UINT_PTR _timer; - UInt32 _startTime; - CMyFont _font; - - UInt64 ramSize; - bool ramSize_Defined; - - bool OnSize(WPARAM /* wParam */, int xSize, int ySize); - bool OnTimer(WPARAM timerID, LPARAM callback); - virtual bool OnInit(); - void OnRestartButton(); - void OnStopButton(); - void OnHelp(); - virtual void OnCancel(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); - bool OnCommand(int code, int itemID, LPARAM lParam); - - void PrintTime(); - void PrintRating(UInt64 rating, UINT controlID); - void PrintUsage(UInt64 usage, UINT controlID); - void PrintResults( - UInt32 dictionarySize, - const CBenchInfo2 &info, UINT usageID, UINT speedID, UINT rpuID, UINT ratingID, - bool decompressMode = false); - - UInt32 GetNumberOfThreads(); - UInt32 OnChangeDictionary(); - void OnChangeSettings(); - - void SetItemText_Number(int itemID, UInt64 val, LPCTSTR post = NULL); - -public: - CBenchProgressSync Sync; - bool TotalMode; - CObjectVector<CProperty> Props; - - CSysString Bench2Text; - - CBenchmarkDialog(): _timer(0), TotalMode(false) {} - INT_PTR Create(HWND wndParent = 0) - { - BIG_DIALOG_SIZE(332, 228); - return CModalDialog::Create(TotalMode ? IDD_BENCH_TOTAL : SIZED_DIALOG(IDD_BENCH), wndParent); - } - void MessageBoxError(LPCWSTR message) - { - MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR); - } -}; +const UInt32 k_NumBenchIterations_Default = 10; HRESULT Benchmark( DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector<CProperty> &props, HWND hwndParent = NULL); + const CObjectVector<CProperty> &props, UInt32 numIterations, HWND hwndParent = NULL); #endif diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.rc b/CPP/7zip/UI/GUI/BenchmarkDialog.rc index a8455a0f..3e73e46d 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.rc +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.rc @@ -23,25 +23,29 @@ #define g4x (m + m) -#define sRating 60 -#define sSpeed 60 -#define sUsage 60 -#define sRpu 60 -#define sFreq 34 +#define sRating 58 +#define sSpeed 60 +#define sUsage 46 +#define sRpu 58 +#define sSize 52 +// #define sFreq 34 #define xRating (xs - m - m - sRating) #define xRpu (xRating - sRpu) #define xUsage (xRpu - sUsage) #define xSpeed (xUsage - sSpeed) +#define xSize (xSpeed - sSize) -#define xFreq (xUsage - sFreq) +// #define xFreq (xUsage - sFreq) -#define sLabel (xUsage - g4x) +#define sLabel (xSize - g4x) #define sTotalRating (sUsage + sRpu + sRating + m + m) #define xTotalRating (xs - m - sTotalRating) -#define g2xs 58 -#define g3xs 36 +#define sPasses 60 + +#define g2xs 60 +#define g3xs 64 #define g3x (m + g2xs) #undef GROUP_Y_SIZE @@ -56,7 +60,10 @@ #define g7xs bx1 - m - g0xs - g1xs - m -IDD_BENCH DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX +#define sLog 140 + 0 + +// MY_MODAL_DIALOG_STYLE +IDD_BENCH DIALOG 0, 0, xs + sLog, ys MY_MODAL_RESIZE_DIALOG_STYLE | WS_MINIMIZEBOX CAPTION "Benchmark" MY_FONT BEGIN @@ -70,71 +77,79 @@ BEGIN COMBOBOX IDC_BENCH_DICTIONARY, g1x, m, g1xs, 140, MY_COMBO LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m - 2, g7xs, 8 - LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, 8 + LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, MY_TEXT_NOPREFIX LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 30, g0xs, 8 COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 29, g1xs, 140, MY_COMBO - LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 32, g7xs, 8 + LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 30, g7xs, MY_TEXT_NOPREFIX - RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, 8 - RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, 8 - RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, 8 - RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, 8 + RTEXT "Size", IDT_BENCH_SIZE, xSize, 54, sSize, MY_TEXT_NOPREFIX + RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, MY_TEXT_NOPREFIX + RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, MY_TEXT_NOPREFIX + RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, MY_TEXT_NOPREFIX + RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, MY_TEXT_NOPREFIX GROUPBOX "Compressing", IDG_BENCH_COMPRESSING, m, 64, xc, GROUP_Y_SIZE - LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, 8 - RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, 8 - RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, 8 - RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, 8 - RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, 8 + LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SIZE1, xSize, 76, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, MY_TEXT_NOPREFIX - LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, 8 - RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, 8 - RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, 8 - RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, 8 - RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, 8 + LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SIZE2, xSize, 89, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, MY_TEXT_NOPREFIX GROUPBOX "Decompressing", IDG_BENCH_DECOMPRESSING, m, 111, xc, GROUP_Y_SIZE - LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, 8 - RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, 8 - RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, 8 - RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, 8 - RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, 8 + LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SIZE1, xSize, 123, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, MY_TEXT_NOPREFIX - LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, 8 - RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, 8 - RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, 8 - RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, 8 - RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, 8 + LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SIZE2, xSize, 136, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_ERROR_MESSAGE, m, 155, xc, MY_TEXT_NOPREFIX + GROUPBOX "Total Rating", IDG_BENCH_TOTAL_RATING, xTotalRating, 163, sTotalRating, GROUP_Y2_SIZE - RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, 8 - RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, 8 - RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, 8 + RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, MY_TEXT_NOPREFIX - RTEXT "", IDT_BENCH_CPU, m, 202, xc, 8 - RTEXT "", IDT_BENCH_VER, m + xc - 100, 216, 100, 8 + // RTEXT "", IDT_BENCH_CPU, m + sPasses, 202, xc - sPasses, 16, SS_NOPREFIX + RTEXT "", IDT_BENCH_CPU, m + 0, 202, xc - 0, 16, SS_NOPREFIX + RTEXT "", IDT_BENCH_VER, m + xc - 100, 222, 100, MY_TEXT_NOPREFIX - LTEXT "", IDT_BENCH_CPU_FEATURE, m, 228, xc - 100, 8 - LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, 8 - LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, 8 - - // LTEXT "", IDT_BENCH_SYSTEM, m, 232, xc - 80, 8 - // LTEXT "", IDT_BENCH_FREQ_RES, m, 242, 80, 8 - + LTEXT "", IDT_BENCH_CPU_FEATURE, m, 222, xc - 100, 16, SS_NOPREFIX // - 100 + LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, MY_TEXT_NOPREFIX + LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, MY_TEXT_NOPREFIX + + LTEXT "", IDT_BENCH_LOG, m + xc + m, m, sLog - m, yc, SS_LEFTNOWORDWRAP | SS_NOPREFIX LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 163, g2xs, 8 - LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8 - LTEXT "Passes:", IDT_BENCH_PASSES, m, 189, g2xs, 8 +// LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8 + LTEXT "Passes:", IDT_BENCH_PASSES, m, 176, g2xs, 8 + COMBOBOX IDC_BENCH_NUM_PASSES, m, 187, sPasses, 140, MY_COMBO + + RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, MY_TEXT_NOPREFIX + // RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX - RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, 8 - RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, 8 - RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 189, g3xs, 8 END #ifdef UNDER_CE diff --git a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h index 8ee4f681..b7d54b77 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h +++ b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h @@ -38,9 +38,17 @@ #define IDT_BENCH_TOTAL_USAGE_VAL 133 #define IDT_BENCH_ELAPSED_VAL 140 -#define IDT_BENCH_SIZE_VAL 141 +// #define IDT_BENCH_SIZE_VAL 141 #define IDT_BENCH_PASSES_VAL 142 +#define IDC_BENCH_NUM_PASSES 143 +#define IDT_BENCH_LOG 160 +#define IDT_BENCH_ERROR_MESSAGE 161 + +#define IDT_BENCH_COMPRESS_SIZE1 170 +#define IDT_BENCH_COMPRESS_SIZE2 171 +#define IDT_BENCH_DECOMPR_SIZE1 172 +#define IDT_BENCH_DECOMPR_SIZE2 173 // #define IDT_BENCH_FREQ_CUR 150 // #define IDT_BENCH_FREQ_RES 151 diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp index 9f2cb146..3298526e 100644 --- a/CPP/7zip/UI/GUI/CompressDialog.cpp +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp @@ -83,6 +83,8 @@ static const unsigned kHistorySize = 20; static const UInt32 kNoSolidBlockSize = 0; static const UInt32 kSolidBlockSize = 64; +static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; + static LPCSTR const kExeExt = ".exe"; #define k7zFormat "7z" @@ -254,18 +256,20 @@ static bool IsMethodSupportedBySfx(int methodID) return false; } -static bool GetMaxRamSizeForProgram(UInt64 &physSize) +static bool GetMaxRamSizeForProgram(UInt64 &ramSize, UInt64 &size) { - physSize = (UInt64)(sizeof(size_t)) << 29; - bool ramSize_Defined = NSystem::GetRamSize(physSize); + size = (UInt64)(sizeof(size_t)) << 29; + bool ramSize_Defined = NSystem::GetRamSize(size); + ramSize = size; + size = size / 16 * 15; const UInt64 kMinSysSize = (1 << 24); - if (physSize <= kMinSysSize) - physSize = 0; + if (size <= kMinSysSize) + size = 0; else - physSize -= kMinSysSize; + size -= kMinSysSize; const UInt64 kMinUseSize = (1 << 24); - if (physSize < kMinUseSize) - physSize = kMinUseSize; + if (size < kMinUseSize) + size = kMinUseSize; return ramSize_Defined; } @@ -411,7 +415,7 @@ bool CCompressDialog::OnInit() SetSolidBlockSize(); SetNumThreads(); - TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 }; + TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 }; ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2); SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s); @@ -687,6 +691,48 @@ static bool IsAsciiString(const UString &s) return true; } + +static void AddSize_MB(UString &s, UInt64 size) +{ + char temp[32]; + ConvertUInt64ToString((size + (1 << 20) - 1) >> 20, temp); + s += temp; + s += " MB"; +} + + +void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString) +{ + s += "The operation was blocked by 7-Zip"; + s.Add_LF(); + s += "The operation can require big amount of RAM (memory):"; + s.Add_LF(); + s.Add_LF(); + AddSize_MB(s, reqSize); + + if (!usageString.IsEmpty()) + { + s += " : "; + s += usageString; + } + + s.Add_LF(); + AddSize_MB(s, ramSize); + s += " : RAM"; + + if (ramLimit != 0) + { + s.Add_LF(); + AddSize_MB(s, ramLimit); + s += " : 7-Zip limit"; + } + + s.Add_LF(); + s.Add_LF(); + s += LangString(IDS_MEM_ERROR); +} + + void CCompressDialog::OnOK() { _password1Control.GetText(Info.Password); @@ -718,6 +764,24 @@ void CCompressDialog::OnOK() } } + { + UInt64 ramSize; + UInt64 maxRamSize; + const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize); + UInt64 decompressMem; + const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); + if (maxRamSize_Defined && memUsage > maxRamSize) + { + UString s; + UString s2 = LangString(IDT_COMPRESS_MEMORY); + if (s2.IsEmpty()) + GetItemText(IDT_COMPRESS_MEMORY, s2); + SetErrorMessage_MemUsage(s, memUsage, ramSize, maxRamSize, s2); + MessageBoxError(s); + return; + } + } + SaveOptionsInMem(); { UString s; @@ -736,7 +800,7 @@ void CCompressDialog::OnOK() Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()]; Info.Level = GetLevelSpec(); - Info.Dictionary = GetDictionarySpec(); + Info.Dict64 = GetDictSpec(); Info.Order = GetOrderSpec(); Info.OrderMode = GetOrderMode(); Info.NumThreads = GetNumThreadsSpec(); @@ -1207,29 +1271,37 @@ UString CCompressDialog::GetEncryptionMethodSpec() return s; } -void CCompressDialog::AddDictionarySize(UInt32 size) + +void CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow) { Byte c = 0; unsigned moveBits = 0; - if ((size & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } - else if ((size & 0x3FF) == 0) { moveBits = 10; c = 'K'; } - TCHAR s[40]; - ConvertUInt32ToString(size >> moveBits, s); + if ((sizeShow & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } + else if ((sizeShow & 0x3FF) == 0) { moveBits = 10; c = 'K'; } + TCHAR s[32]; + ConvertUInt64ToString(sizeShow >> moveBits, s); unsigned pos = MyStringLen(s); s[pos++] = ' '; if (moveBits != 0) s[pos++] = c; s[pos++] = 'B'; s[pos++] = 0; - int index = (int)m_Dictionary.AddString(s); - m_Dictionary.SetItemData(index, size); + const int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, sizeReal); } + +void CCompressDialog::AddDict(size_t size) +{ + AddDict2(size, size); +} + + void CCompressDialog::SetDictionary() { m_Dictionary.ResetContent(); const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormat(ai.Name); + const int index = FindRegistryFormat(ai.Name); UInt32 defaultDict = (UInt32)(Int32)-1; if (index >= 0) @@ -1239,12 +1311,13 @@ void CCompressDialog::SetDictionary() defaultDict = fo.Dictionary; } - int methodID = GetMethodID(); - UInt32 level = GetLevel2(); + const int methodID = GetMethodID(); + const UInt32 level = GetLevel2(); if (methodID < 0) return; + UInt64 ramSize; UInt64 maxRamSize; - bool maxRamSize_Defined = GetMaxRamSizeForProgram(maxRamSize); + const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize); switch (methodID) { @@ -1254,38 +1327,44 @@ void CCompressDialog::SetDictionary() if (defaultDict == (UInt32)(Int32)-1) { defaultDict = - ( level <= 3 ? (1 << (level * 2 + 16)) : - ( level <= 6 ? (1 << (level + 19)) : - ( level <= 7 ? (1 << 25) : (1 << 26) - ))); + ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : + ( level <= 6 ? ((UInt32)1 << (level + 19)) : + ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) + ))); } - AddDictionarySize(1 << 16); - AddDictionarySize(1 << 18); - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + + // we use threshold 3.75 GiB to switch to kLzmaMaxDictSize. + if (defaultDict >= ((UInt32)15 << 28)) + defaultDict = kLzmaMaxDictSize; - for (unsigned i = 20; i <= 31; i++) - for (unsigned j = 0; j < 2; j++) - { - if (i == 20 && j > 0) - continue; - UInt32 dict = ((UInt32)(2 + j) << (i - 1)); - - if (dict > - #ifdef MY_CPU_64BIT - (3 << 29) - #else - (1 << 26) - #endif - ) - continue; - - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if (dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } + const size_t kLzmaMaxDictSize_Up = (size_t)1 << (20 + sizeof(size_t) / 4 * 6); + + int curSel = 0; + for (unsigned i = (16 - 1) * 2; i <= (32 - 1) * 2; i++) + { + if (i < (20 - 1) * 2 + && i != (16 - 1) * 2 + && i != (18 - 1) * 2) + continue; + if (i == (20 - 1) * 2 + 1) + continue; + const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); + size_t dict = dict_up; + if (dict_up >= kLzmaMaxDictSize) + dict = kLzmaMaxDictSize; // we reduce dictionary + + AddDict(dict); + // AddDict2(dict, dict_up); // for debug : we show 4 GB + + const UInt64 memUsage = GetMemoryUsageComp_Dict(dict); + if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize)) + curSel = m_Dictionary.GetCount() - 1; + if (dict_up >= kLzmaMaxDictSize_Up) + break; + } + + m_Dictionary.SetCurSel(curSel); // SetNearestSelectComboBox(m_Dictionary, defaultDict); break; } @@ -1293,46 +1372,63 @@ void CCompressDialog::SetDictionary() case kPPMd: { if (defaultDict == (UInt32)(Int32)-1) - { defaultDict = (UInt32)1 << (level + 19); - } - for (unsigned i = 20; i < 31; i++) - for (unsigned j = 0; j < 2; j++) - { - if (i == 20 && j > 0) - continue; - UInt32 dict = ((UInt32)(2 + j) << (i - 1)); - if (dict > - #ifdef MY_CPU_64BIT - (1 << 30) - #else - (1 << 29) - #endif - ) - continue; - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - || m_Dictionary.GetCount() == 1) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + const size_t kPpmd_MaxDictSize_Up = (size_t)1 << (29 + sizeof(size_t) / 8); + + if (defaultDict >= ((UInt32)15 << 28)) // threshold + defaultDict = kPpmd_Default_4g; + + int curSel = 0; + for (unsigned i = (20 - 1) * 2; i <= (32 - 1) * 2; i++) + { + if (i == (20 - 1) * 2 + 1) + continue; + + const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); + size_t dict = dict_up; + if (dict_up >= kPpmd_Default_4g) + dict = kPpmd_Default_4g; + + AddDict2(dict, dict_up); + // AddDict2((UInt32)((UInt32)0 - 2), dict_up); // for debug + // AddDict(dict_up); // for debug + const UInt64 memUsage = GetMemoryUsageComp_Dict(dict); + if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize)) + curSel = m_Dictionary.GetCount() - 1; + if (dict_up >= kPpmd_MaxDictSize_Up) + break; + } + m_Dictionary.SetCurSel(curSel); // SetNearestSelectComboBox(m_Dictionary, defaultDict); break; } - case kDeflate: + case kPPMdZip: { - AddDictionarySize(32 << 10); - m_Dictionary.SetCurSel(0); + if (defaultDict == (UInt32)(Int32)-1) + defaultDict = (UInt32)1 << (level + 19); + + int curSel = 0; + for (unsigned i = 20; i <= 28; i++) + { + const UInt32 dict = (UInt32)1 << i; + AddDict(dict); + const UInt64 memUsage = GetMemoryUsageComp_Dict(dict); + if ((dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize))) + curSel = m_Dictionary.GetCount() - 1; + } + m_Dictionary.SetCurSel(curSel); + // SetNearestSelectComboBox(m_Dictionary, defaultDict); break; } - + + case kDeflate: case kDeflate64: { - AddDictionarySize(64 << 10); + const UInt32 dict = (methodID == kDeflate ? (UInt32)(1 << 15) : (UInt32)(1 << 16)); + AddDict(dict); m_Dictionary.SetCurSel(0); break; } @@ -1346,39 +1442,22 @@ void CCompressDialog::SetDictionary() else defaultDict = (100 << 10); } + int curSel = 0; for (unsigned i = 1; i <= 9; i++) { - UInt32 dict = ((UInt32)i * 100) << 10; - AddDictionarySize(dict); - if (dict <= defaultDict || m_Dictionary.GetCount() == 0) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + const UInt32 dict = ((UInt32)i * 100) << 10; + AddDict(dict); + // AddDict2(i * 100000, dict); + if (i <= defaultDict / 100000) + curSel = m_Dictionary.GetCount() - 1; } - - break; - } - - case kPPMdZip: - { - if (defaultDict == (UInt32)(Int32)-1) - defaultDict = (UInt32)1 << (level + 19); - - for (unsigned i = 20; i <= 28; i++) - { - UInt32 dict = (1 << i); - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - || m_Dictionary.GetCount() == 1) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - - // SetNearestSelectComboBox(m_Dictionary, defaultDict); + m_Dictionary.SetCurSel(curSel); break; } } } + UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax) { if (c.GetCount() <= defMax) @@ -1386,6 +1465,15 @@ UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defM return (UInt32)c.GetItemData_of_CurSel(); } + +UInt64 CCompressDialog::GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax) +{ + if (c.GetCount() <= defMax) + return (UInt64)(Int64)-1; + // LRESULT is signed. so we cast it to unsigned size_t at first: + return (UInt64)(size_t)c.GetItemData_of_CurSel(); +} + UInt32 CCompressDialog::GetLevel2() { UInt32 level = GetLevel(); @@ -1396,7 +1484,7 @@ UInt32 CCompressDialog::GetLevel2() int CCompressDialog::AddOrder(UInt32 size) { - TCHAR s[40]; + TCHAR s[32]; ConvertUInt32ToString(size, s); int index = (int)m_Order.AddString(s); m_Order.SetItemData(index, size); @@ -1517,7 +1605,7 @@ bool CCompressDialog::GetOrderMode() } -static UInt64 Get_Lzma2_ChunkSize(UInt32 dict) +static UInt64 Get_Lzma2_ChunkSize(UInt64 dict) { // we use same default chunk sizes as defined in 7z encoder and lzma2 encoder UInt64 cs = (UInt64)dict << 2; @@ -1543,8 +1631,8 @@ void CCompressDialog::SetSolidBlockSize(bool useDictionary) if (level == 0) return; - UInt32 dict = GetDictionarySpec(); - if (dict == (UInt32)(Int32)-1) + UInt64 dict = GetDictSpec(); + if (dict == (UInt64)(Int64)-1) dict = 1; UInt32 defaultBlockSize = (UInt32)(Int32)-1; @@ -1603,7 +1691,7 @@ void CCompressDialog::SetSolidBlockSize(bool useDictionary) if (defaultBlockSize == (UInt32)(Int32)-1 && ((UInt64)1 << i) >= blockSize) defaultBlockSize = i; - TCHAR s[40]; + TCHAR s[32]; char post; ConvertUInt32ToString(1 << (i % 10), s); if (i < 20) post = 'K'; @@ -1665,7 +1753,7 @@ void CCompressDialog::SetNumThreads() numAlgoThreadsMax = 128; for (UInt32 i = 1; i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++) { - TCHAR s[40]; + TCHAR s[32]; ConvertUInt32ToString(i, s); int index = (int)m_NumThreads.AddString(s); m_NumThreads.SetItemData(index, (UInt32)i); @@ -1673,7 +1761,8 @@ void CCompressDialog::SetNumThreads() SetNearestSelectComboBox(m_NumThreads, defaultValue); } -UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) + +UInt64 CCompressDialog::GetMemoryUsage_Dict_DecompMem(UInt64 dict64, UInt64 &decompressMemory) { decompressMemory = UInt64(Int64(-1)); UInt32 level = GetLevel2(); @@ -1706,6 +1795,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) case kLZMA: case kLZMA2: { + const UInt32 dict = (dict64 >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dict64); UInt32 hs = dict - 1; hs |= (hs >> 1); hs |= (hs >> 2); @@ -1757,7 +1847,15 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) } if (chunkSize == 0) - size += numBlockThreads * (size1 + (UInt64)dict * 3 / 2); + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict + (1 << 16) + + (numThreads1 > 1 ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + size += numBlockThreads * (size1 + blockSize); + } else { size += numBlockThreads * (size1 + chunkSize); @@ -1771,7 +1869,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) case kPPMd: { - decompressMemory = dict + (2 << 20); + decompressMemory = dict64 + (2 << 20); return size + decompressMemory; } @@ -1799,7 +1897,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) case kPPMdZip: { - decompressMemory = dict + (2 << 20); + decompressMemory = dict64 + (2 << 20); return size + (UInt64)decompressMemory * numThreads; } } @@ -1807,9 +1905,15 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) return (UInt64)(Int64)-1; } -UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory) +UInt64 CCompressDialog::GetMemoryUsage_DecompMem(UInt64 &decompressMemory) { - return GetMemoryUsage(GetDictionary(), decompressMemory); + return GetMemoryUsage_Dict_DecompMem(GetDict(), decompressMemory); +} + +UInt64 CCompressDialog::GetMemoryUsageComp_Dict(UInt64 dict64) +{ + UInt64 decompressMemory; + return GetMemoryUsage_Dict_DecompMem(dict64, decompressMemory); } void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) @@ -1819,7 +1923,7 @@ void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) SetItemText(res, TEXT("?")); return; } - TCHAR s[40]; + TCHAR s[32]; if (value <= ((UInt64)16 << 30)) { value = (value + (1 << 20) - 1) >> 20; @@ -1838,7 +1942,7 @@ void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) void CCompressDialog::SetMemoryUsage() { UInt64 decompressMem; - UInt64 memUsage = GetMemoryUsage(decompressMem); + const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage); PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem); } @@ -1847,7 +1951,7 @@ void CCompressDialog::SetParams() { const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; m_Params.SetText(TEXT("")); - int index = FindRegistryFormat(ai.Name); + const int index = FindRegistryFormat(ai.Name); if (index >= 0) { const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; @@ -1858,13 +1962,34 @@ void CCompressDialog::SetParams() void CCompressDialog::SaveOptionsInMem() { const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; - int index = FindRegistryFormatAlways(ai.Name); + const int index = FindRegistryFormatAlways(ai.Name); m_Params.GetText(Info.Options); Info.Options.Trim(); NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; fo.Options = Info.Options; fo.Level = GetLevelSpec(); - fo.Dictionary = GetDictionarySpec(); + { + const UInt64 dict64 = GetDictSpec(); + UInt32 dict32; + if (dict64 == (UInt64)(Int64)-1) + dict32 = (UInt32)(Int32)-1; + else + { + dict32 = (UInt32)dict64; + if (dict64 != dict32) + { + /* here we must write 32-bit value for registry that indicates big_value + (UInt32)(Int32)-1 : is used as marker for default size + (UInt32)(Int32)-2 : it can be used to indicate big value (4 GiB) + the value must be larger than threshold + */ + dict32 = (UInt32)(Int32)-2; + // dict32 = kLzmaMaxDictSize; // it must be larger than threshold + } + } + fo.Dictionary = dict32; + } + fo.Order = GetOrderSpec(); fo.Method = GetMethodSpec(); fo.EncryptionMethod = GetEncryptionMethodSpec(); diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h index 6658de5c..234e0239 100644 --- a/CPP/7zip/UI/GUI/CompressDialog.h +++ b/CPP/7zip/UI/GUI/CompressDialog.h @@ -42,7 +42,7 @@ namespace NCompressDialog UInt32 Level; UString Method; - UInt32 Dictionary; + UInt64 Dict64; bool OrderMode; UInt32 Order; UString Options; @@ -79,7 +79,8 @@ namespace NCompressDialog DeleteAfterCompressing(false), FormatIndex(-1) { - Level = Dictionary = Order = UInt32(-1); + Level = Order = (UInt32)(Int32)-1; + Dict64 = (UInt64)(Int64)(-1); OrderMode = false; Method.Empty(); Options.Empty(); @@ -88,6 +89,7 @@ namespace NCompressDialog }; } + class CCompressDialog: public NWindows::NControl::CModalDialog { NWindows::NControl::CComboBox m_ArchivePath; @@ -142,17 +144,19 @@ class CCompressDialog: public NWindows::NControl::CModalDialog void SetEncryptionMethod(); - void AddDictionarySize(UInt32 size); + void AddDict2(size_t sizeReal, size_t sizeShow); + void AddDict(size_t size); void SetDictionary(); UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0); + UInt64 GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax = 0); UInt32 GetLevel() { return GetComboValue(m_Level); } UInt32 GetLevelSpec() { return GetComboValue(m_Level, 1); } UInt32 GetLevel2(); - UInt32 GetDictionary() { return GetComboValue(m_Dictionary); } - UInt32 GetDictionarySpec() { return GetComboValue(m_Dictionary, 1); } + UInt64 GetDict() { return GetComboValue_64(m_Dictionary); } + UInt64 GetDictSpec() { return GetComboValue_64(m_Dictionary, 1); } UInt32 GetOrder() { return GetComboValue(m_Order); } UInt32 GetOrderSpec() { return GetComboValue(m_Order, 1); } UInt32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); } @@ -166,8 +170,10 @@ class CCompressDialog: public NWindows::NControl::CModalDialog void SetSolidBlockSize(bool useDictionary = false); void SetNumThreads(); - UInt64 GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory); - UInt64 GetMemoryUsage(UInt64 &decompressMemory); + UInt64 GetMemoryUsage_Dict_DecompMem(UInt64 dict, UInt64 &decompressMemory); + UInt64 GetMemoryUsage_DecompMem(UInt64 &decompressMemory); + UInt64 GetMemoryUsageComp_Dict(UInt64 dict64); + void PrintMemUsage(UINT res, UInt64 value); void SetMemoryUsage(); void SetParams(); @@ -196,6 +202,11 @@ public: CCompressDialog(): CurrentDirWasChanged(false) {}; + void MessageBoxError(LPCWSTR message) + { + MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR); + } + protected: void CheckSFXControlsEnable(); diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp index f5676d85..37567019 100644 --- a/CPP/7zip/UI/GUI/GUI.cpp +++ b/CPP/7zip/UI/GUI/GUI.cpp @@ -193,7 +193,12 @@ static int Main2() if (options.Command.CommandType == NCommandType::kBenchmark) { - HRESULT res = Benchmark(EXTERNAL_CODECS_VARS_L options.Properties); + HRESULT res = Benchmark( + EXTERNAL_CODECS_VARS_L + options.Properties, + options.NumIterations_Defined ? + options.NumIterations : + k_NumBenchIterations_Default); /* if (res == S_FALSE) { diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp index 41c1e04d..7e65f481 100644 --- a/CPP/7zip/UI/GUI/GUI.dsp +++ b/CPP/7zip/UI/GUI/GUI.dsp @@ -1164,6 +1164,10 @@ SOURCE=..\..\..\Windows\SystemInfo.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\TimeUtils.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp index af07e550..28f19d25 100644 --- a/CPP/7zip/UI/GUI/UpdateGUI.cpp +++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp @@ -142,7 +142,7 @@ static void SetOutProperties( UInt32 level, bool setMethod, const UString &method, - UInt32 dictionary, + UInt64 dict64, bool orderMode, UInt32 order, bool solidIsSpecified, UInt64 solidBlockSize, @@ -157,13 +157,13 @@ static void SetOutProperties( { if (!method.IsEmpty()) AddProp(properties, is7z ? "0": "m", method); - if (dictionary != (UInt32)(Int32)-1) + if (dict64 != (UInt64)(Int64)-1) { AString name; if (is7z) name = "0"; name += (orderMode ? "mem" : "d"); - AddProp(properties, name, GetNumInBytesString(dictionary)); + AddProp(properties, name, GetNumInBytesString(dict64)); } if (order != (UInt32)(Int32)-1) { @@ -389,7 +389,7 @@ static HRESULT ShowDialog( di.Level, !methodOverride, di.Method, - di.Dictionary, + di.Dict64, di.OrderMode, di.Order, di.SolidIsSpecified, di.SolidBlockSize, di.MultiThreadIsAllowed, di.NumThreads, diff --git a/CPP/7zip/warn_clang_mac.mak b/CPP/7zip/warn_clang_mac.mak index 41044a2c..aadf14f7 100644 --- a/CPP/7zip/warn_clang_mac.mak +++ b/CPP/7zip/warn_clang_mac.mak @@ -27,6 +27,8 @@ CFLAGS_WARN_CLANG_12= $(CFLAGS_WARN_CLANG_3_8) \ -Wno-atomic-implicit-seq-cst \ -Wconversion \ -Wno-sign-conversion \ + -Wno-suggest-override \ + -Wno-suggest-destructor-override \ CFLAGS_WARN_MAC = \ -Wno-poison-system-directories \ diff --git a/CPP/7zip/warn_gcc.mak b/CPP/7zip/warn_gcc.mak index 5fb747dc..3185326a 100644 --- a/CPP/7zip/warn_gcc.mak +++ b/CPP/7zip/warn_gcc.mak @@ -42,6 +42,10 @@ CFLAGS_WARN_GCC_9 = \ # -Wno-sign-conversion \ +CFLAGS_WARN_GCC_10 = $(CFLAGS_WARN_GCC_9) \ + -Wmaybe-uninitialized \ + -Wmisleading-indentation \ + CFLAGS_WARN_GCC_PPMD_UNALIGNED = \ -Wno-strict-aliasing \ |