디렉토리를 항상 캐시에 두십시오.


35

전체 c ++ 프로젝트를 컴파일하는 데 걸리는 시간을 향상시키기 위해 다양한 방법을 테스트했습니다. 현재 ~ 5 분이 소요됩니다. distcc, ccache 등을 실험했습니다. 최근에 전체 프로젝트를 RAM 드라이브에 복사 한 다음 컴파일하면 컴파일 시간이 원본의 30 % (1.5 분)로 단축됩니다.

분명히, RAM 드라이브에서 작업하는 것은 실용적이지 않습니다. 그래서 누구나 OS가 항상 특정 디렉토리를 캐시하도록 유지하는 방법을 알고 있습니까? 나는 여전히 디렉토리가 평소처럼 디스크에 다시 동기화되기를 원하지만 항상 메모리에 데이터 사본을 원합니다. 이것이 가능한가?

편집 : 가능한 해결책으로, 우리는 rsync10 초마다 실행되는 데몬을 시작 하여 디스크 드라이브를 RAM 드라이브와 동기화하려고 생각했습니다 . 그런 다음 RAM 드라이브에서 컴파일을 실행합니다. 은 rsync빨리 타오르는됩니다 만, 정말 일 것이다? 분명히 OS가 더 잘할 수 있습니다 ....


캐시는 tmpfs와 ext3 / 4의 유일한 차이점은 아닙니다. 예를 들어, 캐싱에 관계없이 작성되는 저널링이 있습니다.
André Paramés

1
time편집 한 결과를 우리와 공유 할 수 있습니까? 일부 논쟁을 불러 일으킬 것입니다. make clean && /usr/bin/time -v make(bash 내장 time명령을 사용하지 마십시오 )
shellholic

1
@she 왜 내장 명령을 bash하지 않습니까?
tshepang 2013

3
@Tshepang time내장 된 bash ( help time)는 man timeI / O, 컨텍스트 전환에 관한 GNU 시간 ( ) 보다 세부 사항이 적습니다 (자세한 옵션은 없습니다) .
shellholic

답변:


18

캐시에 많은 파일을 보관하는 확실한 방법은 파일에 자주 액세스하는 것입니다. 리눅스는 스와핑과 캐싱을 중재하는 데 상당히 능숙하므로 관찰 한 속도 차이는 실제로 OS에 캐시를 보관하지 않는 것이 아니라 tmpfs 사용과 다른 시도 사이의 다른 차이 때문이라고 생각합니다.

각 경우에 IO가 수행하는 작업을 관찰하십시오. 이를위한 기본 도구는 iotop입니다. 다른 도구가 유용 할 수 있습니다. 파일 시스템 경로 및 / 또는 프로세스 별 Linux 디스크 IO로드 분석을 참조하십시오 . , Linux에서 어떤 프로그램이 시간이 지남에 따라 I / O를 측정 할 수 있습니까? 및 서버 결함의 기타 스레드.

다음은 어떤 일이 일어날 수 있는지에 대한 몇 가지 가설입니다. 측정 할 경우 이러한 가설을 확인하거나 반증 할 수 있도록 표시하십시오.

  • 파일 액세스 시간 이 켜져 있으면 OS에서 이러한 액세스 시간을 쓰는 데 시간이 많이 걸릴 수 있습니다. 액세스 트리는 컴파일 트리에 쓸모가 없으므로 noatime마운트 옵션 으로 해제해야합니다 . tmpfs + rsync 솔루션 은 하드 디스크에서 읽지 않으므로 시간을 쓰는 데 추가 시간을 소비 할 필요가 없습니다.
  • 컴파일러가 호출 하거나 커널이 출력 버퍼를 자주 플러시하기 때문에 쓰기가 동기화되는 경우 쓰기는 sync()tmpfs보다 하드 디스크에 더 오래 걸립니다.

나도이 느낌이 있습니다. 컴파일은 IO가 아니라 CPU를 많이 사용합니다.
phunehehe 2019

흠, 나는 Gilles 가설을 확인하거나 거부하는 @JaredC의 의견을보고 싶습니다. 1.5 분과 5 분 간의 차이는 상당히 큰 차이입니다.
Daniel Alder

8

Linux 는 기본적으로 RAM을 디스크 캐시로 사용합니다. 데모로 time find /some/dir/containing/a/lot/of/files > /dev/null두 번 실행 해보 십시오. 두 번째는 모든 디스크 inode가 캐시되므로 훨씬 빠릅니다. 여기서 핵심은이 커널 기능을 사용하고이를 교체하려는 시도를 중지하는 방법입니다.

요점은을 변경하는 것 swappiness입니다. 활성 프로그램, 비활성 프로그램 및 디스크 캐시의 세 가지 주요 메모리 사용 유형을 고려해 봅시다. 분명히 활성 프로그램이 사용하는 메모리를 교체해서는 안되며 다른 두 가지 중에서 선택하는 것은 매우 임의적입니다. 빠른 프로그램 전환 또는 빠른 파일 액세스를 원하십니까? 낮은 swappiness는 선호 메모리에 프로그램을 유지 (오랫동안 사용하지 않을 경우에도)과 높은 swappiness는 것을 좋아 더 많은 디스크 캐시를 유지 (사용하지 않는 프로그램을 스와핑). (스왑 규모는 0에서 100 사이이며 기본값은 60입니다.)

귀하의 문제에 대한 나의 해결책은 swappiness를 매우 높게 (100-95는 말하지 않음) 변경하고 캐시를로드하는 것입니다.

echo 95 | sudo tee /proc/sys/vm/swappiness > /dev/null # once after reboot
find /your/source/directory -type f -exec cat {} \; > /dev/null

짐작할 수 있듯이 컴파일러, 헤더 파일, 링크 된 라이브러리, IDE 및 기타 사용 된 프로그램뿐만 아니라 모든 소스 파일과 객체 파일을 캐시에 보관할 수있는 충분한 여유 메모리가 있어야합니다.


이것은 일반적으로 유용하지만, 실제로 원하는 것은 소스 코드가 낮은 스왑 피스를 갖지만 다른 모든 것들은 정상적인 스왑 피스를 갖는 것입니다. 본질적으로 백그라운드에서 많은 일이 진행되고 있지만 소스 코드에 다른 2GB를 항상 유지하면서 6GB 중 6GB 로 제한하고 싶습니다 . 나는 그것이 성가신 때문에 스왑 될 가능성을 원하지 않습니다.
JaredC

교환은 시스템 전체에 적용됩니다. 실제로 다른 작업을 수행하고 파일이 메모리에서 언로드되면 두 번째 줄로 다시로드해야합니다. 다른 것을 위해 메모리를 확보해야하는 경우, 스왑에서 수행 할 "기회를 원치 않습니다". tmpfs같은 경우 BTW 도 교체됩니다.
shellholic

2
개인적으로 나는 높은 스왑 성을 떨어 뜨렸다는 것은 워크 스테이션에서 엄청나게 무서운 것입니다. 더 큰 캐시 (즉, 더 많은 캐시 된 파일)에 의해 일부 기능이 가속화 될 수 있지만 이는 대가가됩니다. 브라우저에서 사무실로, 다른 브라우저에서 전자 메일로 전환 할 때 각 프로그램이 다시 스왑 인 될 때까지 1-2 초 정도 기다릴 필요가 없습니다. 모든 Linux 컴퓨터에서 일반적으로 swappiness를 낮은 값 10으로 설정했습니다.
fgysin reinstate Monica

6

캐시를 강제 실행하는 것이 올바른 방법이 아닙니다. 소스를 하드 드라이브에 유지하고 tmpfs에서 컴파일하는 것이 좋습니다. qmake 및 CMake와 같은 많은 빌드 시스템은 소스 외부 빌드를 지원합니다.


6

inosync좋아 데몬 소리는 램 디스크에 rsync를 위하여려고하는 경우에 당신이 원하는 것을 정확히 않습니다. 약 10 초마다 재 동기화하는 대신 파일의 변경시 Linux의 inotify 기능을 사용하여 재 동기화합니다. inosync패키지 로 데비안 저장소에서 찾았 거나 소스는 http://bb.xnull.de/projects/inosync/ 에서 찾을 수 있습니다 .


꽤 유용한 것 같습니다. 나는 그것을 조사하고 다시보고합니다. 감사!
JaredC

5

특정 파일 또는 모든 파일을 특정 디렉토리의 캐시에 보관하려면이 작업이 효과가있는 것 같습니다.

vmtouch 는 그 일을하는 것처럼 보입니다. 예 5 필요한 것이있을 수 있습니다.

vmtouch -dl /whatever/directory/

루트로 실행해야했습니다. sudo


1
새 / 제거 된 파일이 표시되지 않습니다.
Vi.

3

충분한 메모리가 제공되면 램 디스크에서 빌드 할 때 I / O가 수행되지 않습니다. 이렇게하면 파일을 읽거나 쓰는 속도가 빨라질 수 있습니다. I / O는 가장 느린 작업 중 하나입니다. 빌드 전에 모든 것이 캐시 되더라도 영향을 최소화해야하지만 쓰기 용 I / O가 여전히 있습니다.

모든 파일을 캐시에 미리로드하면 속도가 향상 될 수 있지만이 시간은 총 빌드 시간에 포함되어야합니다. 이것은 많은 이점을 제공하지 않을 수 있습니다.

객체와 중간 파일을 디스크가 아닌 RAM에 빌드합니다. 증분 빌드를 수행하면 빈번한 빌드에서 상당한 이익을 얻을 수 있습니다. 대부분의 프로젝트에서 매일 클린 빌드와 증분 빌드를 수행합니다. 통합 빌드는 항상 깨끗한 빌드이지만 하루에 한 개 미만으로 제한하려고합니다.

atime이 꺼진 상태에서 ext2 파티션을 사용하면 약간의 성능을 얻을 수 있습니다. 소스는 ext3 / 4와 같은 저널 파일 시스템에서 버전을 제어해야합니다.


2

앞에서 언급했듯이, 확실한 방법은 캐시하려는 모든 디렉토리 구조와 파일 내용을 읽는 것입니다.

스크립트를 작성하여 vmstat 1(OS에 해당하는 도구를 사용 하여) 출력을 모니터링하고 쓰고 읽은 블록 수의 합계를 유지하여 스크립트를 작성하여 자동화 할 수 있습니다 . 합계가 선택한 임계 값을 초과하면 캐시하려는 모든 파일을 읽고 합계를 재설정 한 다음 vmstat 출력 모니터링을 계속하십시오. 파일을 빠르게 읽으려면 : 트리에 많은 파일이 포함 된 경우 find ... -exec cat대신 피 find ... -print0 | xargs -0 cat하거나 각 파일에 대해 cat을 실행하지 않는 사용자 정의 프로그램을 사용하십시오.

디스크 IO 모니터링은 고정 된 간격을 사용하는 것보다 좋습니다. 디스크 IO로드에 따라 데이터를 더 자주 또는 덜 읽도록 신호하기 때문입니다.

하드 드라이브 I / O를 피하면서 항상 빠른 인덱스 파일 읽기가 필요한 시스템에서이 자동화 된 방법을 성공적으로 사용했습니다. 또한 strace를 사용하여 로그인 할 때 액세스되는 모든 파일 목록을 작성하여 빠른 로그인을 위해 모든 것을 캐시에 보관할 수 있습니다.

이것은 최선의 해결책은 아니지만 나에게 적합합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.