2017-01-29 2 views
1

csplit을 사용하여 파일을 자동으로 4 부분으로 나눈 다음 하나의 쉘 프로그램을 작성한 후 nohup을 사용하여 백그라운드에서 동일한 명령을 실행하는 4 개의 쉘 프로그램을 작성하고 루프가 이들 4 개의 프로세스의 완료를 찾은 다음 마지막으로 cat output1.txt를 찾습니다. ... output4.txt> finaloutput.txtUnix 명령의 병렬 실행?

하지만이 명령에 대해 알게되면 parallel 큰 파일로 시도했지만 예상대로 작동하지 않는 것 같습니다. 이 파일은 다음 명령의 출력 -

for i in $(seq 1 1000000);do cat /etc/passwd >> data.txt1;done 

time wc -l data.txt1 
10000000 data.txt1 

real 0m0.507s 
user 0m0.080s 
sys  0m0.424s 

병렬

time cat data.txt1 | parallel --pipe wc -l | awk '{s+=$1} END {print s}' 
10000000 

real 0m41.984s 
user 0m1.122s 
sys  0m36.251s 

와 내가 2 기가 바이트 파일 (~ 1000 만) 기록이 시도하는 경우는 20 분 이상 걸렸다.

이 명령은 네 .. 당신은 병렬에서 혜택을 얻을 수있는 시스템에 대한 물리적 코어가 필요합니다 즉

nproc --all 
1 
+0

우리에게 액세스 권한을 부여 할 수있는 data.txt1을 사용하도록 예제를 변경할 수 있습니까? 귀하의시기는 매우 극단적이므로, 귀하가 운영하는 기계에 대해 더 많이 알아야합니다. –

+0

@OleTange - 요청한대로 파일 데이터의 논리를 첨부했으며이 명령을 개발 한 사람입니까? –

+1

나는 저자 다. 컴퓨터와 다른 컴퓨터에서 아래에 나와있는 테스트를 시도해야합니다. 나는 네 컴퓨터가 어떻게 든 부서 졌다고 생각해. –

답변

1

--pipe은 비효율적입니다 (측정하는 척도가 아니지만 시스템에 어떤 것이 잘못되었습니다). 1GB/s (총)의 순서로 제공 할 수 있습니다.

--pipepart은 반대로 매우 효율적입니다. 디스크가 충분히 빠르면 코어 당 1GB/s의 속도로 제공 할 수 있습니다. 이것은 가장 효율적인 처리 방법 인 data.txt1이어야합니다. 그것은 CPU 코어 당 하나 개의 블록으로의 data.txt1을 분할하고 각각의 코어에서 실행되는 wc -l에 그 블록을 공급한다 :

parallel --block -1 --pipepart -a data.txt1 wc -l 

당신은 20,161,222 이상 block -1가 작동하려면 버전이 필요합니다.

이것은 이전 듀얼 코어 노트북의 타이밍입니다.seq 200000000은 1.8GB의 데이터를 생성합니다.

$ time seq 200000000 | LANG=C wc -c 
1888888898 

real 0m7.072s 
user 0m3.612s 
sys  0m2.444s 

$ time seq 200000000 | parallel --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 1m28.101s 
user 0m25.892s 
sys  0m40.672s 

여기 시간은 각 1메가바이트 블록에 대한 새로운 wc -c을 산란 병렬 GNU에 주로 기인한다. 블록 크기를 늘리면 더 빨리한다 :

$ seq 200000000 > data.txt1 
$ time parallel --block -1 --pipepart -a data.txt1 LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m2.242s 
user 0m0.424s 
sys  0m2.880s 

그래서 내 옛날 노트북에 나는 2.2 초에서 1.8 GB를 처리 할 수 ​​있습니다 :

$ time seq 200000000 | parallel --block 10m --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m26.269s 
user 0m8.988s 
sys  0m11.920s 

$ time seq 200000000 | parallel --block 30m --pipe LANG=C wc -c | awk '{s+=$1} END {print s}' 
1888888898 

real 0m21.628s 
user 0m7.636s 
sys  0m9.516s 

으로는 파일에 데이터가있는 경우 --pipepart 빨리 많이 언급했다.

코어가 하나만 있고 작업이 CPU에 종속적이면 병렬 처리가 도움이되지 않습니다. 단일 코어 머신에서 병렬 처리는 대부분의 시간이 대기 (예 : 네트워크 대기)에 소비되면 의미가 있습니다.

그러나 컴퓨터의 타이밍에 따라 뭔가 잘못되었다고합니다. 다른 컴퓨터에서 프로그램을 테스트 해 보길 권합니다.

+0

감사합니다 --diskpart를 통지 해 주셔서 감사합니다. 나는 그것을 모르고 있었다. :) – Mandar

0

(나는 현재 싱글 코어 시스템을 사용하고 있습니다) 멀티 코어 시스템에서 작동합니까. 당신의 업무를 이해하기 위해서; 다음은

file1 is a 10,000,000 line file 

split into 4 files > 
file1.1 > processing > output1 
file1.2 > processing > output2 
file1.3 > processing > output3 
file1.4 > processing > output4 

>> cat output* > output 
________________________________ 

을 할 의도 그리고 당신은 중간 부분을 병렬화 동시에 4 개의 코어 (잘하면 4 개 코어)에서 실행하고자하는 것입니다. 나 맞아? 난 당신이 -j는 프로세서의 번호 인 경우 (psuedocode 경고)와 명령 파일과 사용의 1

parallel --jobs 4 "processing code on the file segments with sequence variable {}" ::: 1 2 3 4 

를 코드를 쓰기 훨씬 더 나은 방법으로 GNU 평행을 사용할 수 있다고 생각합니다.

업데이트 왜 파일 내에서 순차적 실행을 위해 병렬 명령을 사용하려고합니까? 1.2 1.3 및 1.4 ?? 당신이

parallel 'for i in $(seq 1 250000);do cat file1.{} >> output{}.txt;done' ::: 1 2 3 4 
위의 코드는 4 개 코어

for i in $(seq 1 250000);do cat file1.1 >> output1.txt;done 
for i in $(seq 1 250000);do cat file1.2 >> output2.txt;done 
for i in $(seq 1 250000);do cat file1.3 >> output3.txt;done 
for i in $(seq 1 250000);do cat file1.4 >> output4.txt;done 

에 병렬로 csplit에서 4 개 분할 된 파일을 실행합니다

를 코딩 한대로 내가 그 확신 일반 순차적으로 처리하자 - Ole이 위에서 제안한 diskpart가 더 좋은 방법입니다. 당신은 HDD로부터 고속 데이터 액세스를 가지고 있다고 가정합니다.

+0

명령을 시도했지만 작동하지 않습니다. 오류 (파일 또는 디렉토리 없음)가 표시됩니다. time cat data.txt1 | 병렬 - 직업 4 wc -l | awk '{s + = $ 1} END {print s}' 아래 명령은 정상적으로 작동하지만 더 많은 시간이 걸립니다. - time cat data.txt1 | 병렬 - 파이프 wc -l | awk '{s + = $ 1} END {print s}' –

+0

또 하나의 병목 현상으로 HDD의 읽기 속도가 빨라질 수 있습니다. 일반 HDD에 4 개의 스레드를 시작하는 경우 (습격 없음) 속도가 느려질 수 있습니다. Btw 왜 도대체 cat data.txt1을 병렬로 연결하고 있습니까? 첫 번째 file1.1 1.2 1.3 및 1.4를 만들 수 있습니다. 완료되면 4 개의 파일 모두에 대해 병렬 실행을 동시에 생성하고 출력을 얻습니다 .2.3.3.4 ... 해당 프로세스가 완료 될 때까지 기다립니다. 그런 다음 출력을 연결하십시오. 내 생각 엔 당신이 평행선을 잘못 사용하고 있다는 것입니다. – Mandar