[windows] C ++를 컴파일하기 위해 Windows를 Linux만큼 빠르게 실행하려면 어떻게해야합니까?

나는 이것이 프로그래밍 문제가 아니라 관련성이 있다는 것을 알고있다.

저는 상당히 큰 크로스 플랫폼 프로젝트를 진행하고 있습니다. Windows에서는 VC ++ 2008을 사용합니다. Linux에서는 gcc를 사용합니다. 프로젝트에는 약 40k 개의 파일이 있습니다. Windows는 동일한 프로젝트를 컴파일하고 링크 할 때 Linux보다 10 배에서 40 배 정도 느립니다. 어떻게 고칠 수 있습니까?

Linux에서 단일 변경 증분 빌드 20 초, Windows에서> 3 분 왜? Linux에 ‘골드’링커를 설치하고 그 시간을 7 초로 줄일 수도 있습니다.

마찬가지로 git은 Windows보다 Linux에서 10x ~ 40x 빠릅니다.

자식의 경우 git이 Windows를 최적의 방식으로 사용하지 않고 VC ++을 사용할 수 있습니까? 마이크로 소프트는 자신의 개발자가 가능한 한 생산성을 높이기를 원할 것이라고 생각할 것이고, 빠른 컴파일은 그와는 거리가 멀다. 아마도 개발자가 C #을 장려하려고 노력하고 있습니까?

간단한 테스트로 많은 하위 폴더가있는 폴더를 찾아서

dir /s > c:\list.txt

Windows에서. 두 번 실행하고 두 번째 실행 시간을 지정하여 캐시에서 실행하십시오. 파일을 Linux에 복사하고 동등한 2 회 실행과 두 번째 실행 시간을 수행하십시오.

ls -R > /tmp/list.txt

정확히 동일한 사양을 가진 2 대의 워크 스테이션이 있습니다. 12gig 램, 3.0ghz에서 8 코어의 HP Z600 ~ 400k 파일이있는 폴더에서 Windows는 40 초, Linux는 1 초 미만입니다.

Windows 속도를 높이기 위해 설정할 수있는 레지스트리 설정이 있습니까? 무엇을 제공합니까?


컴파일 시간과 관련된 약간의 관련 링크는 반드시 i / o 일 필요는 없습니다.



답변

하드 코어 Windows 시스템 해커가 등장하지 않는 한, 당신은 당파적인 의견 (내가하지 않을 것)과 추측 (내가 시도 할 것) 이상을 얻지 못할 것입니다.

  1. 파일 시스템-동일한 파일 시스템에서 동일한 작업 (을 포함하여 dir)을 시도해야합니다 . 나는 이것을 가로 질러왔다다양한 매개 변수에 대해 몇 가지 파일 시스템을 벤치마킹하는 를 .

  2. 캐싱. 한때 RAM 디스크에서 Linux에서 컴파일을 시도했지만 커널이 캐싱을 처리하는 방식으로 인해 디스크에서 실행하는 것보다 느리다는 것을 알았습니다. 이것은 Linux의 확실한 판매 지점이며 성능이 다른 이유 일 수 있습니다.

  3. Windows의 종속성 사양이 잘못되었습니다. Windows의 크롬 종속 사양이 Linux만큼 정확하지 않을 수 있습니다. 작은 변경을하면 불필요한 컴파일이 발생할 수 있습니다. Windows에서 동일한 컴파일러 툴체인을 사용하여이를 확인할 수 있습니다.


답변

몇 가지 아이디어 :

  1. 8.3 이름을 비활성화하십시오. 많은 파일과 비교적 적은 수의 폴더가있는 드라이브에서 이는 큰 요인이 될 수 있습니다.fsutil behavior set disable8dot3 1
  2. 더 많은 폴더를 사용하십시오. 내 경험상 NTFS는 폴더 당 약 1000 개가 넘는 파일로 속도가 느려집니다.
  3. MSBuild로 병렬 빌드를 사용하십시오. “/ m”스위치 만 추가하면 CPU 코어 당 하나의 MSBuild 복사본이 자동으로 시작됩니다.
  4. 파일을 SSD에 저장하면 임의 I / O에 큰 도움이됩니다.
  5. 평균 파일 크기가 4KB보다 훨씬 큰 경우 평균 파일 크기와 대략적으로 더 큰 클러스터 크기로 파일 시스템을 재구성하는 것이 좋습니다.
  6. 파일이 조각 모음되었는지 확인하십시오. 조각난 파일은 많은 디스크 검색을 유발하므로 처리량을 40 배 이상 높일 수 있습니다. sysinternals의 “contig”유틸리티 또는 기본 제공 Windows 조각 모음을 사용하십시오.
  7. 평균 파일 크기가 작고 현재 파티션이 상대적으로 가득 찬 경우 조각난 MFT로 실행 중일 수 있으며 이는 성능에 좋지 않습니다. 또한 1K보다 작은 파일은 MFT에 직접 저장됩니다. 위에서 언급 한 “contig”유틸리티가 도움이되거나 MFT 크기를 늘려야 할 수도 있습니다. 다음 명령은 볼륨을 25 %로 두 배 늘립니다.fsutil behavior set mftzone 2 . 마지막 숫자를 3 또는 4로 변경하여 크기를 추가로 12.5 % 씩 증가시킵니다. 명령을 실행 한 후 재부팅 한 후 파일 시스템을 작성하십시오.
  8. 마지막 액세스 시간을 비활성화하십시오. fsutil behavior set disablelastaccess 1
  9. 인덱싱 서비스 비활성화
  10. 안티 바이러스 및 안티 스파이웨어 소프트웨어를 비활성화하거나 최소한 관련 폴더를 무시하도록 설정하십시오.
  11. 파일을 OS 및 페이징 파일과 다른 실제 드라이브에 넣습니다. 별도의 물리적 드라이브를 사용하면 Windows가 두 드라이브 모두에 ​​병렬 I / O를 사용할 수 있습니다.
  12. 컴파일러 플래그를 살펴보십시오. Windows C ++ 컴파일러에는 수많은 옵션이 있습니다. 당신이 정말로 필요한 것을 사용하고 있는지 확인하십시오.
  13. OS가 페이지 풀 버퍼에 사용하는 메모리 양을 늘리십시오 (먼저 RAM이 충분한 지 확인하십시오). fsutil behavior set memoryusage 2
  14. 때때로 디스크 오류가 발생하지 않는지 Windows 오류 로그를 확인하십시오.
  15. 실제 디스크 관련 성능 카운터를보고 디스크 사용량이 많은지 확인하십시오. 큐 길이가 길거나 전송 당 시간이 길다는 것은 잘못된 신호입니다.
  16. 디스크 파티션의 처음 30 %는 원시 전송 시간 측면에서 나머지 디스크보다 훨씬 빠릅니다. 좁은 파티션은 탐색 시간을 최소화하는 데 도움이됩니다.
  17. RAID를 사용하고 있습니까? 그렇다면 RAID 유형 선택을 최적화해야 할 수도 있습니다 (RAID-5는 컴파일과 같이 쓰기가 많은 작업에는 좋지 않습니다)
  18. 필요하지 않은 서비스 비활성화
  19. 폴더 조각 모음 : 모든 파일을 다른 드라이브 (파일 만)로 복사하고, 원본 파일을 삭제하고, 모든 폴더를 다른 드라이브 (빈 폴더 만)로 복사 한 다음 원래 폴더를 삭제하고, 원본 드라이브의 조각 모음을 수행하고, 폴더 구조를 먼저 복사하십시오. 파일을 복사하십시오. Windows에서 한 번에 하나의 파일로 큰 폴더를 만들면 폴더가 조각화되고 느려집니다. ( “contig”도 여기에 도움이됩니다)
  20. I / O에 바인딩되어 있고 여분의 CPU주기가있는 경우 디스크 압축을 켜십시오. CPU 비용이 약간 들고, 압축률이 높은 파일 (예 : 소스 코드)의 속도를 크게 높일 수 있습니다.

답변

NTFS는 매번 파일 액세스 시간을 절약합니다. 비활성화 할 수 있습니다 : “fsutil behavior set disablelastaccess 1″(다시 시작)


답변

내가 알 수 있듯이 비주얼 C ++의 문제는 컴파일러 팀 이이 시나리오를 최적화하는 것이 우선 순위가 아니라는 것입니다. 그들의 해결책은 미리 컴파일 된 헤더 기능을 사용하는 것입니다. 이것은 Windows 특정 프로젝트가 수행 한 작업입니다. 휴대용이 아니지만 작동합니다.

또한 Windows에는 일반적으로 바이러스 스캐너가 있으며 buid 폴더를 모니터링하면 빌드 시간을 완전히 망칠 수있는 시스템 복원 및 검색 도구가 있습니다. windows 7 resouce 모니터를 사용하면 쉽게 찾을 수 있습니다. 정말 관심이 있다면 vc ++ 빌드 시간을 최적화하기위한 추가 팁 이 있는 답변이 있습니다 .


답변

개인적으로 Linux에서 Windows 가상 머신을 실행하면 Windows에서 많은 IO 속도 저하를 제거 할 수 있습니다 .Linux vm은 ​​Windows 자체가 아니었던 많은 캐싱을 수행했기 때문일 수 있습니다.

그렇게하면 15 분에서 6 분 정도의 작업을 수행하는 큰 (250Kloc) C ++ 프로젝트의 컴파일 시간을 단축 할 수있었습니다.


답변

이를 수행하는 데있어 어려움은 C ++이 자체적으로 확산되는 경향이 있고 컴파일 프로세스가 여러 개의 작은 개별 파일에 분산되기 때문입니다. 그것은 Linux가 좋고 Windows가 그렇지 않은 것입니다. Windows에서 정말 빠른 C ++ 컴파일러를 만들려면 모든 것을 RAM에 유지하고 파일 시스템을 가능한 한 적게 만지십시오.

또한 Linux C ++ 컴파일 체인을 더 빠르게 만드는 방법이지만 파일 시스템이 이미 많은 조정 작업을 수행하고 있기 때문에 Linux에서는 덜 중요합니다.

그 이유는 Unix 문화 때문입니다. 역사적으로 파일 시스템 성능은 Windows보다 Unix 세계에서 훨씬 높은 우선 순위였습니다. Windows에서는 우선 순위가 아니라고 말하지 않고 Unix에서는 우선 순위가 높았습니다.

  1. 소스 코드에 액세스

    제어 할 수없는 것을 변경할 수 없습니다. Windows NTFS 소스 코드에 액세스 할 수 없다는 것은 성능 향상을위한 대부분의 노력이 하드웨어를 개선 한 것이 었음을 의미합니다. 즉, 성능이 느리면 버스, 저장 매체 등의 하드웨어를 개선하여 문제점을 해결하십시오. 문제를 해결하지 않고 해결해야하는 경우에만 그렇게 할 수 있습니다.

    오픈 소스 이전에도 유닉스 소스 코드에 대한 액세스가 더 널리 퍼졌습니다. 따라서 성능을 향상 시키려면 소프트웨어를 우선 (더 저렴하고 쉽게), 하드웨어를 우선으로 해결해야합니다.

    그 결과, 유닉스 파일 시스템을 연구하고 성능을 개선 할 수있는 새로운 방법을 찾아 세상에 많은 사람들이 박사 학위를 받았습니다.

  2. 유닉스는 많은 작은 파일을 선호합니다. Windows는 몇 개의 큰 파일을 선호합니다.

    유닉스 응용 프로그램은 많은 작은 파일을 처리하는 경향이 있습니다. 소프트웨어 개발 환경을 생각해보십시오. 각각의 용도에 따라 여러 개의 작은 소스 파일이 있습니다. 마지막 단계 (링크)는 하나의 큰 파일을 만들지 만 적은 비율입니다.

    결과적으로 Unix는 파일 열기 및 닫기, 디렉토리 스캔 등을위한 시스템 호출을 최적화했습니다. 유닉스 리서치의 역사는 디렉토리 액세스 (조회 및 ​​전체 디렉토리 스캔), 초기 파일 열기 등을 개선하는 데 많은 관심을 기울인 수십 년의 파일 시스템 최적화에 걸쳐 있습니다.

    Windows 응용 프로그램은 하나의 큰 파일을 열고, 오랫동안 열어 둔 상태에서 완료되면 닫는 경향이 있습니다. MS-Word를 생각하십시오. msword.exe (또는 기타)는 파일을 한 번 열고 몇 시간 동안 추가하고 내부 블록을 업데이트하는 등의 작업을 수행합니다. 파일 열기 최적화의 가치는 시간 낭비입니다.

    Windows 벤치마킹 및 최적화의 역사는 긴 파일을 얼마나 빨리 읽거나 쓸 수 있는지에 관한 것입니다. 그것이 최적화되는 것입니다.

    슬프게도 소프트웨어 개발은 ​​첫 번째 상황으로 향했습니다. 유닉스 (TeX / LaTeX)를위한 최고의 워드 프로세싱 시스템 인 Heck은 각 챕터를 다른 파일에 넣고 모두 함께 포함하도록 권장합니다.

  3. 유닉스는 고성능에 중점을두고 있습니다. Windows는 사용자 경험에 중점을 둡니다.

    서버 룸에서 유닉스 시작 : 사용자 인터페이스 없음. 사용자가 볼 수있는 유일한 것은 속도입니다. 따라서 속도가 우선입니다.

    Windows가 데스크톱에서 시작되었습니다. 사용자는 자신이 보는 것만 신경 쓰고 UI를 봅니다. 따라서 성능보다 UI를 개선하는 데 더 많은 에너지가 소비됩니다.

  4. Windows 에코 시스템은 계획된 노후화에 의존합니다. 새 하드웨어가 1 년에서 2 년 거리에있을 때 소프트웨어를 최적화해야하는 이유

    음모론을 믿지는 않지만 Windows 문화에서는 성능을 향상시킬 인센티브가 적습니다. Windows 비즈니스 모델은 시계와 같은 새로운 기계를 구입하는 사람들에 따라 다릅니다. (따라서 MS가 운영 체제를 늦게 배송하거나 인텔이 칩 출시 날짜를 놓치면 수천 개 회사의 주가에 영향을 미치는 이유입니다.) 이는 사람들에게 새로운 하드웨어를 구매하도록 지시함으로써 성능 문제를 해결하는 인센티브가 있다는 것을 의미합니다. 실제 문제를 개선하는 것이 아니라 느린 운영 체제. 유닉스는 예산이 부족한 학계 출신이며 파일 시스템을 더 빠르게 만드는 새로운 방법을 발명함으로써 박사 학위를 취득 할 수 있습니다. 학계의 누군가가 구매 주문을 발행하여 문제를 해결하기위한 포인트를 얻는 경우는 거의 없습니다.

    또한 유닉스는 오픈 소스이기 때문에 (아직 소스가 아니더라도 모든 사람이 소스에 액세스 할 수 있음) 지루한 PhD 학생은 코드를 읽고 더 잘함으로써 유명해질 수 있습니다. Windows에서는 그런 일이 발생하지 않습니다 (MS에는 학계에서 Windows 소스 코드에 액세스 할 수있는 프로그램이 있으므로 거의 활용되지 않습니다). 이 유닉스 관련 공연 논문들 ( http://www.eecs.harvard.edu/margo/papers/)을 보거나 Osterhaus, Henry Spencer 또는 다른 사람들의 논문 역사를 찾아보십시오. 유닉스 역사상 가장 큰 (그리고 가장보기 좋은) 토론 중 하나 인 오스터 하우스 (Osterhaus)와 셀저 (Selzer)의 앞뒤 . html
    Windows 세계에서는 이런 일이 일어나지 않습니다. 당신은 벤더가 서로를 위로하는 것을 볼 수 있지만, 혁신이 모두 표준 신체 수준에있는 것처럼 보이기 때문에 요즘 훨씬 더 드문 것 같습니다.

그것이 내가 보는 방법입니다.

업데이트 : Microsoft에서 제공하는 새로운 컴파일러 체인을 살펴보면 전체 툴체인을 RAM으로 유지하고 작업을 덜 반복하여 수행하는 작업이 많아 지므로 매우 낙관적입니다. 매우 인상적인 것들.


답변

증분 연결

VC 2008 솔루션이 .lib 출력을 가진 여러 프로젝트로 설정된 경우 “라이브러리 종속성 입력 사용”을 설정해야합니다. 이렇게하면 링커가 .lib가 아닌 .obj 파일에 직접 연결됩니다. (실제로 점진적으로 링크합니다.)

디렉토리 탐색 성능

원래 머신에서 디렉토리 크롤링을 다른 머신에서 동일한 파일로 새로 작성된 디렉토리를 크롤링하는 것과 비교하는 것은 다소 불공평합니다. 동등한 테스트를 원한다면 소스 머신에 다른 디렉토리 사본을 작성해야합니다. (아직 속도가 느릴 수 있지만 디스크 조각화, 짧은 파일 이름, 백그라운드 서비스 등 여러 가지로 인해 발생할 수 있습니다.) 성능 문제는 dir /s실제 파일을 측정하는 것보다 출력을 작성하는 것과 더 관련이 있다고 생각 합니다. 순회 성능. dir /s /b > nul거대한 디렉토리가있는 내 컴퓨터 에서도 느립니다.