저는 xargs
호출 Python 스크립트를 사용하여 약 3천만 개의 작은 파일을 처리하고 있습니다. 병렬화 프로세스를 사용하고 싶습니다 xargs
. 내가 사용하는 명령은 다음과 같습니다.
find ./data -name "*.json" -print0 |
xargs -0 -I{} -P 40 python Convert.py {} > log.txt
기본적으로 Convert.py
초등학교 정도는 읽을 수 있어요JSON파일(4kb)을 처리하고 또 다른 4kb 파일을 작성합니다. 저는 40개의 CPU 코어가 있는 서버에서 실행 중입니다. 그리고 서버에서는 CPU를 많이 사용하는 다른 프로세스가 실행되지 않습니다.
htop을 모니터링하여(그런데 CPU 성능을 모니터링하는 다른 좋은 방법이 있습니까?) -P 40
예상만큼 빠르지 않다는 것을 발견했습니다. 때때로 모든 코어가 정지되어 3-4초 동안 거의 0으로 떨어졌다가 60-70%로 복구됩니다. 그런 다음 병렬 프로세스 수를 로 줄이려고 시도했지만 -P 20-30
여전히 속도가 그리 빠르지 않습니다. 이상적인 동작은 선형 가속입니다. xargs를 병렬로 사용하는 것에 대한 제안 사항이 있습니까?
답변1
나는 당신의 문제가 다음과 같다고 장담합니다.파이썬. 각 파일에 어떤 처리가 이루어지는지는 밝히지 않았지만, 단지 메모리의 데이터만 처리한다고 가정하면, 3천만 개의 Python 가상 머신(인터프리터)이 실행되어 런타임이 지배하게 됩니다.
단일 파일 대신 파일 목록을 가져오도록 Python 프로그램을 리팩터링할 수 있으면 성능이 크게 향상됩니다. 그런 다음 xargs를 사용하여 성능을 더욱 향상시킬 수 있습니다. 예를 들어 40개의 프로세스가 있고 각각 1000개의 파일을 처리합니다.
find ./data -name "*.json" -print0 |
xargs -0 -L1000 -P 40 python Convert.py
이것은 파이썬이 나쁘고 느린 언어라고 말하는 것이 아닙니다. 그것은 나쁘고 느린 언어입니다. 시작 시간에 최적화되지 않았습니다. 이를 가상 머신 기반 언어 또는 해석된 언어로 볼 수 있습니다. 예를 들어 Java는 훨씬 더 나쁩니다. 프로그램이 C로 작성된 경우 각 파일을 처리하기 위해 별도의 운영 체제 프로세스를 시작하는 데 여전히 비용이 들지만 비용은 훨씬 적습니다.
거기에서 -P
데이터를 읽고 쓰는 동안 유휴 프로세서를 활용하기 위해 프로세스 수를 늘려 속도를 약간 높일 수 있는지 확인할 수 있습니다.
답변2
따라서 먼저 제약 조건을 고려하십시오.
각 직업별 한도는 어떻게 되나요? I/O라면 괜찮습니다.아마도I/O 제한에 도달할 때까지 CPU 코어당 여러 작업을 실행할 수 있지만, CPU 집약적이라면 무의미하게 CPU 코어보다 많은 작업을 동시에 실행하는 것보다 더 나쁩니다.
이러한 것들에 대한 나의 이해는GNU 병렬작업 대기열 등을 더욱 효과적으로 제어할 수 있습니다.
바라보다GNU 병렬 대 &(배경을 의미함) 대 xargs -P두 가지가 어떻게 다른지에 대한 자세한 설명을 알아보세요.
답변3
다른 사람들이 말했듯이 I/O 바인딩되어 있는지 확인하십시오. 또한 xargs의 매뉴얼 페이지에서는 -n
with 사용을 제안하지만 병렬로 실행되는 프로세스 수는 언급하지 않습니다 -P
.Convert.py
제안으로, I/O 바인딩된 경우 SSD 블록 장치를 사용해 보거나 tmpfs에서 시도해 볼 수 있습니다(물론 이 경우 tmpfs로 인한 스왑을 피하기 위해 메모리가 충분한지 확인해야 합니다). (내 생각에는) 그리고 애초에 데이터를 복사하는 오버헤드도 있습니다.