2013-10-18 117 views
1

我有一個8核心CPU與8GB內存,我創建一個批處理文件來自動化7-zip CLI在耗盡大多數參數和變量來壓縮相同最終目標是找到最強大的參數和變量組合,從而實現最小的檔案大小。爲並行和順序工作批處理和啓動命令

這本質上是非常耗時的,特別是當要處理的文件集是千兆字節時。我需要一種不僅自動化而且加速整個過程的方法。

7-ZIP的作品有不同的壓縮算法,有些是單線程只,還有一些是多線程的,一些並不需要的內存量多,有的需要它的大量的,甚至可能超過8GB屏障。我已經成功地創建了一個自動化的批處理序列,它排除了需要超過8GB內存的組合。

我已經分幾批分解了不同的壓縮算法,以簡化整個過程。例如,在PPMd中作爲7z壓縮文件壓縮使用1線程和高達1024MB。這是我目前批:

@echo off 
echo mem=1m 2m 3m 4m 6m 8m 12m 16m 24m 32m 48m 64m 96m 128m 192m 256m 384m 512m 768m 1024m 
echo o=2 3 4 5 6 7 8 10 12 14 16 20 24 28 32 
echo s=off 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1g 2g 4g 8g 16g 32g 64g on 
echo x=1 3 5 7 9 

for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s 
exit 

xsomem是參數,什麼是後他們每個人都是其中7z.exe將與變量。在這種情況下,xs是無關緊要的,它們表示存檔的壓縮強度和固體塊大小。

該批處理可以正常工作,但一次只能運行7z.exe的一個實例,現在我正在尋找一種方法使它能夠並行運行更多的7z.exe實例,但不會超過8GB RAM或8個線程,以先到者爲準,然後繼續執行序列中的下一個。

我該如何改進?我有一些想法,但我不知道如何讓他們在一個批次中工作。我正在考慮另外兩個變量,它們不會與7z進程交互,但會控制下一個7z實例何時開始。一個變量會跟蹤當前有多少線程正在使用,另一個會跟蹤正在使用多少內存。這可以工作嗎?

編輯: 對不起,我需要補充資料,我是新來這篇文章風格。回答這個問題 - https://stackoverflow.com/a/19481253/2896127 - 我提到了8個批次都創建了,而7z.PPMd批次就是其中之一。也許列出所有的批次以及7z如何處理這些參數將會對整個問題提供更好的見解。我將從簡單的開始:

  • 7z.PPMd - 1充分利用線程和字典依賴每個實例的32m-1055m內存使用量。
  • 7z.BZip2 - 每個實例8個完全使用的線程和固定的109m內存使用量。
  • zip.Bzip2 - 8個部分使用的線程和每個實例固定的336m內存使用量。
  • zip.Deflate - 每個實例8個部分使用的線程和固定的260m內存使用量。
  • zip.PPMd - 每個實例8個部分使用的線程和字典依賴的280m-2320m內存使用量。

我的意思是部分利用的線程是,雖然我分配了8個線程供每個7.exe實例使用,但算法可以隨機地執行可變CPU使用率,超出我的控制範圍,不可預知,但限制在那裏設置 - 不超過8個線程。在8個充分利用線程的情況下,這意味着我的8芯CPU上,每個實例是利用CPU的100%。

最複雜的 - 7z.LZMA,7z.LZMA2,zip.LZMA - 將需要詳細地解釋,但我在很短的時間,現在運行。我會回來的,每當我有更多的時間來編輯LZMA部分。

再次感謝。


編輯:添加在LZMA部分。

  • 7z.LZMA - 每個實例是正螺紋,範圍從1到2:

    • 1充分利用螺紋,字典依賴性,64K到512M:
      • 64k的字典用途32M內存
      • ...
      • 512米字典使用5407米內存
      • 不含uded範圍:768米到1024米(以上8192米存儲器的可用的極限)
    • 2部分利用線程,字典依賴性,64K到512M:
      • 64k的字典使用38米存儲器
      • ...
      • 512米字典使用5413米存儲器
      • 排除範圍:768米到1024米(以上8192米存儲器的可用的極限)
  • 7z.LZMA2 - 每個實例正螺紋,範圍從1至8:

    • 1充分利用螺紋,字典依賴性,64K到512M:
      • 64k的字典使用32M內存
      • ...
      • 512米字典使用5407米存儲器
      • 排除範圍:768米到1024米(以上8192米存儲器的可用的極限)
    • 2或3部分使用的線程,字典依賴性,64K到512M:
      • 64k的字典使用38米存儲器
      • ...
      • 512米字典使用5413米存儲器
      • 排除範圍:768米到1024米(以上8192米存儲器的可用的極限)
    • 4或5部分使用的線程,字典依賴性,64K爲256M:
      • 64K字典使用51米內存
      • ...
      • 256米字典使用5677米內存
      • 排除[R安格:384米到1024米(以上8192米存儲器的可用的極限)
    • 6或7部分使用的線程,字典依賴性,64K到192米:
      • 64k的字典使用62米存儲器
      • ...
      • 192米字典使用6965米存儲器
      • 排除範圍:256米到1024米(以上8192米存儲器的可用的極限)
    • 8部分使用的線程,字典依賴性,64K至1.28:
      • 64k的字典使用72米存儲器
      • ...
      • 128米字典使用6717米存儲器
    • 排除範圍:192米到1024米(上述8192米存儲器的可用的極限)
  • zip.LZMA - 每個實例是正螺紋,範圍從1至8:

    • 1充分利用螺紋,字典依賴性,64K到512M:
      • 64k的字典使用3米存儲器
      • ...
      • 512米字典使用5378米存儲器
      • 排除範圍:768米到1024m(超過8192m內存的限制)
    • 2或3個部分使用的線程,字典相關,64k t o 512m:
      • 64k字典使用9m內存
      • ...
      • 512米字典使用5384米存儲器
      • 排除範圍:768米到1024米(以上8192米存儲器的可用的極限)
    • 4或5部分使用的線程,字典依賴性,64K爲256M:
      • 64K字典使用82米內存
      • ...
      • 256米字典使用5456米內存
      • 排除[R安格:384米到1024米(以上8192米存儲器的可用的極限)
    • 6或7部分使用的線程,字典依賴性,64K爲256M:
      • 64k的字典使用123米存儲器
      • ...
      • 256米字典使用8184米(非常接近極限雖然,我可以考慮不包括它)
      • 排除範圍:384米到1024米(以上8192米存儲器的可用的極限)
    • 8個部分使用的線程,字典依賴性,64K至1.28:
      • 64k的字典使用164米存儲器
      • ...
      • 128米字典使用5536米存儲器
      • 排除範圍:192米到1024米(以上8192米存儲器的可用的極限)

我想了解這些命令的行爲與nul在他們的行爲。我不太明白那部分發生了什麼,這些符號意味着什麼。

2>nul del %lock%!nextProc! 
    %= Redirect the lock handle to the lock file. The CMD process will  =% 
    %= maintain an exclusive lock on the lock file until the process ends. =% 
    start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd! 
) 
    set "launch=" 

然後後來,在:等待代碼:

) 9>>"%lock%%%N" 
) 2>nul 
    if %endCount% lss %startCount% (
    1>nul 2>nul ping /n 2 ::1 
    goto :wait 
) 

2>nul del %lock%* 

EDIT 2(29-10-2013):添加的情況的當前點。

經過反覆試驗研究,結合發生了什麼的一步一步筆記,我能夠理解上述行爲。我簡化了啓動命令的行:

start /b /low cmd /c !cmd!>"%lock%!nextProc!" 

雖然它的作品,我還是不明白的1^>"filename" 2^>^&1 'command'意義。我知道它與寫在文件名中的文本有關,否則會顯示給我。在這種情況下,它將顯示所有7z.exe文本,但寫入該文件。在7z.exe實例完成其作業之前,文件中沒有寫入任何內容,但該文件已存在,但同時不存在。當7z.exe實際完成時,該文件已完成,並且這次它存在於腳本的下一部分。

現在,我可以理解這個建議的腳本的處理行爲,我用我自己的東西補充它 - 我想實現所有批次爲「一批做到這一切」的劇本。在簡化版本中,它是這樣的:

echo 8 threads - maxproc=1 
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (900k) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=BZip2:d=%%d:mt=%%t 
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (900k) DO 7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.zip .\teste.original\* -mx=%%x -mm=BZip2:d=%%d -mmt=%%t 
for %%x IN (9) DO for %%t IN (8) DO for %%w IN (257 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.deflate64.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate64:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%t IN (8) DO for %%w IN (258 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.deflate.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%t IN (8) DO for %%d IN (256m 128m 64m 32m 16m 8m 4m 2m 1m) DO for %%w IN (16 15 14 13 12 11 10 9 8 7 6 5 4 3 2) DO 7z.exe a teste.resultado\%%xx.ppmd.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=PPMd:mem=%%d:o=%%w -mmt=%%t 

echo 4 threads - maxproc=2 
for %%x IN (9) DO for %%t IN (4) DO for %%d IN (256m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t 

echo 2 threads - maxproc=4 
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%t IN (2) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t 

echo 1 threads - maxproc=8 
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t 
for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s 
for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO 7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t 

總之,我想以最有效的方式處理所有這些。通過確定多少進程可以同時運行在做這將是一個辦法,但再有就是還爲每個進程所需要的內存,使所有需要存儲的這些進程的總和不會超過8192 MB。我有這部分工作。

@echo off 
setlocal enableDelayedExpansion 

set "maxMem=8192" 
set "maxThreads=8" 

:cycle1 
set "cycleCount=4" 
set "cycleThreads=1" 
set "maxProc=" 
set /a "maxProc=maxThreads/cycleThreads" 
set "cycleFor1=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO (" 
set "cycleFor2=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO (" 
set "cycleFor3=for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO for %%w IN (32 28 24 20 16 14 12 10 8 7 6 5 4 3 2) DO for %%s IN (on) DO (" 
set "cycleFor4=for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO (" 
set "cycleCmd1=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t" 
set "cycleCmd2=7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t" 
set "cycleCmd3=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s" 
set "cycleCmd4=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t" 
set "tempMem1=5407" 
set "tempMem2=5407" 
set "tempMem3=1055" 
set "tempMem4=5378" 
rem set "tempMem1=5407" 
rem set "tempMem2=5407" 
rem set "tempMem3=1055 799 543 415 287 223 159 127 95 79 63 55 47 43 39 37 35 34 33 32" 
rem set "tempMem4=5378" 
set "memSum=0" 
if not defined memRem set "memRem=!maxMem!" 

for /l %%N in (1 1 %cycleCount%) DO (set "tempProc%%N=") 
for /l %%N in (1 1 %cycleCount%) DO (
    set memRem 
    set /a "tempProc%%N=%memRem%/tempMem%%N" 
    set /a "memSum+=tempMem%%N" 
    set /a "memRem-=tempMem%%N" 
    set /a "maxProc=!tempProc%%N!" 
    call :executeCycle 
    set /a "memRem+=tempMem%%N" 
    set /a "memSum-=tempMem%%N" 
    set /a "maxProc-=!tempProc%%! 
) 
goto :fim 

:executeCycle 
set "lock=lock_%random%_" 
set /a "startCount=0, endCount=0" 
for /l %%N in (1 1 %maxProc%) DO set "endProc%%N=" 

    set launch=1 
    for %%x IN (9) DO for %%t IN (1) DO for %%d IN (512m) DO for %%w IN (273 256 192 128 96 64 48 32 24 16 12 8) DO for %%s IN (on) DO (
     set "cmd=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t" 
     if !startCount! lss %maxProc% (
     set /a "startCount+=1, nextProc=startCount" 
    ) else (
     call :wait 
    ) 
     set cmd!nextProc!=!cmd! 
     echo !time! - proc!nextProc!: starting !cmd! 
     2>nul del %lock%!nextProc! 
     start /b /low cmd /c !cmd!>"%lock%!nextProc!" 
    ) 
    set "launch=" 
:wait 
     for /l %%N in (1 1 %startCount%) do (
      if not defined endProc%%N if exist "%lock%%%N" (
      echo !time! - proc%%N: finished !cmd%%N! 
      if defined launch (
       set nextProc=%%N 
       exit /b 
      ) 
      set /a "endCount+=1, endProc%%N=1" 
     ) 9>>"%lock%%%N" 
     ) 2>nul 
     if %endCount% lss %startCount% (
     1>nul 2>nul ping /n 2 ::1 
     goto :wait 
    ) 

2>nul del %lock%* 
echo === 
echo Thats all folks! 
exit /b 
:fim 
pause 

我有麻煩cycleFor1cycleCmd1位於:cycle1部分 - 它們應該被替換for線和:executeCycle裏面的第一個cmd變量,讓它工作,我打算。我怎麼做?

其他的問題,我有大約tempMem3。當命令cycleCmd3正在運行時,我已經記錄了所有需要的內存。這是字典依賴。 tempMem3和cycleCmd3的關係如下:

for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO 
set "tempMem3=1055 799 543 415 287 223 159 127 95 79 63 55 47 43 39 37 35 34 33 32" 

所以1024米將使用1055,768米將使用32使用799,依此類推,直到1米我不知道該如何翻譯成劇本。

任何幫助表示讚賞。

+1

爲什麼你這樣做?如果您想要更好/更高效和性能平衡的算法壓縮,爲什麼不使用7ZIP「MAX」標準配置文件,請自行設置字典大小和其他參數? – ElektroStudios

+0

傳統觀點認爲,源文件的字節組成也會影響壓縮大小 - 因此,對於一組測試文件而言,可能最佳的設置對於另一組源文件可能不是最理想的。 – foxidrive

回答

2

我已經張貼在Parallel execution of shell processes限制並行進程的數目強大的批量解決方案。該腳本使用嵌入腳本中的命令列表。按照鏈接查看它是如何工作的。

我修改了腳本生成使用for循環按照你的問題的命令。我還將限制設置爲8個併發進程。

你的最大內存是1g,你從來沒有超過8個進程,所以我不知道你怎麼能超過8g。如果您增加每個進程的最大內存,那麼您不必擔心總內存。您將不得不添加額外的邏輯來跟蹤正在使用多少內存以及哪些cpu ID可用。請注意,批號僅限於〜2g,因此我建議以兆字節計算內存。

默認情況下,腳本隱藏命令的輸出。如果你想看到的輸出,然後用/O選項運行它。

@echo off 
setlocal enableDelayedExpansion 

:: Display the output of each process if the /O option is used 
:: else ignore the output of each process 
if /i "%~1" equ "/O" (
    set "lockHandle=1" 
    set "showOutput=1" 
) else (
    set "lockHandle=1^>nul 9" 
    set "showOutput=" 
) 

:: Define the maximum number of parallel processes to run. 
:: Each process number can optionally be assigned to a particular server 
:: and/or cpu via psexec specs (untested). 
set "maxProc=8" 

:: Optional - Define CPU targets in terms of PSEXEC specs 
::   (everything but the command) 
:: 
:: If a cpu is not defined for a proc, then it will be run on the local machine. 
:: I haven't tested this feature, but it seems like it should work. 
:: 
:: set cpu1=psexec \\server1 ... 
:: set cpu2=psexec \\server1 ... 
:: set cpu3=psexec \\server2 ... 
:: etc. 

:: For this demo force all cpu specs to undefined (local machine) 
for /l %%N in (1 1 %maxProc%) do set "cpu%%N=" 

:: Get a unique base lock name for this particular instantiation. 
:: Incorporate a timestamp from WMIC if possible, but don't fail if 
:: WMIC not available. Also incorporate a random number. 
    set "lock=" 
    for /f "skip=1 delims=-+ " %%T in ('2^>nul wmic os get localdatetime') do (
    set "lock=%%T" 
    goto :break 
) 
    :break 
    set "lock=%temp%\lock%lock%_%random%_" 

:: Initialize the counters 
    set /a "startCount=0, endCount=0" 

:: Clear any existing end flags 
    for /l %%N in (1 1 %maxProc%) do set "endProc%%N=" 

:: Launch the commands in a loop 
    set launch=1 
    echo mem=1m 2m 3m 4m 6m 8m 12m 16m 24m 32m 48m 64m 96m 128m 192m 256m 384m 512m 768m 1024m 
    echo o=2 3 4 5 6 7 8 10 12 14 16 20 24 28 32 
    echo s=off 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1g 2g 4g 8g 16g 32g 64g on 
    echo x=1 3 5 7 9 
    for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO (
    set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s" 
    if !startCount! lss %maxProc% (
     set /a "startCount+=1, nextProc=startCount" 
    ) else (
     call :wait 
    ) 
    set cmd!nextProc!=!cmd! 
    if defined showOutput echo ------------------------------------------------------------------------------- 
    echo !time! - proc!nextProc!: starting !cmd! 
    2>nul del %lock%!nextProc! 
    %= Redirect the lock handle to the lock file. The CMD process will  =% 
    %= maintain an exclusive lock on the lock file until the process ends. =% 
    start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd! 
) 
    set "launch=" 

:wait 
:: Wait for procs to finish in a loop 
:: If still launching then return as soon as a proc ends 
:: else wait for all procs to finish 
    :: redirect stderr to null to suppress any error message if redirection 
    :: within the loop fails. 
    for /l %%N in (1 1 %startCount%) do (
    %= Redirect an unused file handle to the lock file. If the process is =% 
    %= still running then redirection will fail and the IF body will not run =% 
    if not defined endProc%%N if exist "%lock%%%N" (
     %= Made it inside the IF body so the process must have finished =% 
     if defined showOutput echo =============================================================================== 
     echo !time! - proc%%N: finished !cmd%%N! 
     if defined showOutput type "%lock%%%N" 
     if defined launch (
     set nextProc=%%N 
     exit /b 
    ) 
     set /a "endCount+=1, endProc%%N=1" 
    ) 9>>"%lock%%%N" 
) 2>nul 
    if %endCount% lss %startCount% (
    1>nul 2>nul ping /n 2 ::1 
    goto :wait 
) 

2>nul del %lock%* 
if defined showOutput echo =============================================================================== 
echo Thats all folks! 
+0

首先,謝謝。我早些時候會發表評論,但我正在破譯你的解決方案。對於7z格式的PPMd算法來說,它似乎很好用。爲此,我簡化了內存使用情況,但每個實例的實際內存使用情況似乎爲32m + mem,因此,無論何時字典大小設置爲1024m,實際使用的都是1056m,如果設置爲1m大小,則是使用33MB內存。 這只是我八個不同批次中的一個。我試圖從某個地方開始,因爲它的單線程特性,7z.PPMd批處理是我測試中速度最慢的。 – user2896127

1

要在同一時間執行不7z.exe過程中超過8種情況下,你可以這樣做:

@Echo OFF & Setlocal EnableDelayedExpansion 

Set /A "pCount=0" & REm Process count 

For 
... 
) DO (
    Set /A "pCount+=1" 
    If !pCount! LEQ 8 (
     Start /B 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s 
    ) 
) 
... 

如果你想在一個新的並行CMD窗口中運行的每個進程,那麼你會更換Start /B在我的代碼行這個東西:

CMD /C "Start /w 7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s" 
+0

我剛試過這個。它運行前8個實例,但不超過該實例。 CMD/C的第二個選項每次只運行1次,當第8次結束時,它不會再做任何事情。 – user2896127

相關問題