저는 cat
많은 수의 파일을 개별적으로 병합 하려고 합니다 file_X
.file_1
file_100000000000
숫자가 많기 때문에 64개의 CPU가 있는 노드에 작업을 분산하고 각 CPU에서 병렬로 실행했습니다. 각 작업은 하위 폴더에서 실행되므로 64개의 하위 폴더가 있습니다.
놀랍게도 전체 속도는 예상보다 훨씬 느렸습니다.
내가 사용하고 있는 쉘 스크립트는 단순히 각 작업을 file_X
64개 하위 폴더의 상위 디렉토리에 있는 동일한 파일로 지시하기 때문에 여러 CPU가 동시에 동일한 파일을 읽고 있어 각 CPU의 읽기 속도가 느려지는지 궁금합니다.
답변1
예, 아니오.
파일의 실제 읽기는 수행 중인 프로세서 수에 관계없이 동일한 속도로 이루어져야 합니다.
그러나 운영 체제 및 해당 구성에 따라 파일 잠금이 발생할 수 있습니다. 여러 프로세스가 동시에 읽기 잠금을 보유할 수 있지만 잠금 획득 및 잠금 해제는 공유된 뮤텍스 블록에서 이루어져야 합니다. 시스템이 이러한 유형의 잠금을 수행하는 경우 프로세서는 파일에 액세스하기 위해 대기열에 있어야 하며 그런 다음 파일에 더 이상 관심이 없다고 선언하기 위해 대기열에 있어야 합니다.
file_X가 저장된 파일 시스템과 이에 결합된 다양한 파일 및 해당 파일 시스템을 마운트하는 데 사용된 옵션에 따라 cat이 이를 읽을 때마다 file_X의 액세스 시간이 업데이트될 수 있습니다. 이 경우 file_X inode는 각 업데이트 전에 쓰기 잠금이 해제된 후 해제될 가능성이 높습니다.
속도 저하의 또 다른 가능한 이유는 64개 작업 모두가 파일을 병렬로 쓰고 있기 때문입니다. 이 파일은 디스크의 서로 다른 지점에 있어야 합니다. SSD(Solid-State Drive)를 사용하지 않는 한 디스크에서 쓰기 헤드를 많이 이동해야 할 수도 있습니다. 파일은 64개의 서로 다른 디렉터리에 있으므로 생성되는 파일 외에도 업데이트해야 하는 위치가 64개 있습니다.
쉘 스크립트에서 이 모든 활동을 수행한다는 것은 파일의 모든 사본이 분기된다는 것을 의미합니다. Fork는 상당히 비용이 많이 드는 시스템 호출로 간주되지만, 공유 라이브러리가 있는 시스템에서는 모든 공유 라이브러리를 검색하고 모든 공유 라이브러리를 로드해야 하는 exec 시스템 호출 계열의 비용에 비하면 아무것도 아닙니다. 이는 파일이 있는 UNIX 시스템과 구성 방법에 따라 파일에 읽기 잠금이 설정될 수 있는 또 다른 위치입니다.