2016-10-29 3 views
3

Q에 매우 느린 입력/출력을 생성LLVM 연타는 OS X

test_io.cpp :

#include <iostream> 
#include <string> 

constexpr int SIZE = 1000*1000; 

int main(int argc, const char * argv[]) { 
    std::ios_base::sync_with_stdio(false); 
    std::cin.tie(nullptr); 

    std::string command(argv[1]); 
    if (command == "gen") { 
    for (int i = 0; i < SIZE; ++i) { 
     std::cout << 1000*1000*1000 << " "; 
    } 
    } else if (command == "read") { 
    int x; 
    for (int i = 0; i < SIZE; ++i) { 
     std::cin >> x; 
    } 
    } 
} 

컴파일이 OS의 X하에 LLVM 연타이 코드의 IO를 향상시킬 수있다

clang++ -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io 

벤치 마크 :

> time ./test_io gen | ./test_io read 

real 0m2.961s 
user 0m3.675s 
sys  0m0.012s 
그렇다 10메가바이트 파일 비용의 읽기 3 초,이 g보다 훨씬 느린 있다는 슬픈 사실에서 ++ (사제를 통해 설치) 0

:

> gcc-6 -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io 
> time ./test_io gen | ./test_io read 

real 0m0.149s 
user 0m0.167s 
sys  0m0.040s 

내 연타 버전은 Apple LLVM version 7.0.0 (clang-700.0.72)입니다. homebrew (3.7 및 3.8)에서 설치된 clang도 느린 io를 생성합니다. 우분투 (3.8)에 설치된 clang은 빠른 io를 생성합니다. Apple LLVM version 8.0.0은 느린 io를 생성합니다 (2 명이 요청).

나는 또한 조금 ( sudo dtruss -c "./test_io gen | ./test_io read"를) dtrussed 및 GCC 버전은 2079 개 writev 콜을 기울이고 있으나, 그 연타 버전이, 2686 개 write_nocancel 콜을하게 발견했다. 아마도 그 문제의 근원을 가리킬 것입니다.

+0

http://stackoverflow.com/questions/38624468/clang-fstreams-10x-slower- than-g – Danh

+0

시도해 보셨습니까 -O3 – Danh

+0

clang 컴파일 된 버전의 출력을 gcc 컴파일 된 버전으로 보내면 여전히 빠르지 만, gcc로 컴파일 된 버전을 clang으로 컴파일 된 버전으로 보내면, 그것은 천천히 진행됩니다 - 그래서 나는 그것이 clang으로 느린 독서임을 추론합니다. 당신이 공간에서 출력하는 캐릭터를'X'로 바꾸면 속도가 빠르며 빠릅니다. –

답변

3

문제점은 sync_with_stdio를 구현하지 않는 libC++에서 발생합니다.

명령 줄 clang++ -x c++ -lstdc++ -std=c++11 -O2 test_io.cpp -o test_io은 libstdC++를 사용하지 않으며 libC++를 사용합니다. libstdC++를 강제로 사용하려면 -stdlib=libstdc++이 필요합니다.

최소한의 예를 준비 입력 파일이있는 경우 :

int main(int argc, const char * argv[]) { 
    std::ios_base::sync_with_stdio(false); 
    int x; 
    for (int i = 0; i < SIZE; ++i) { 
     std::cin >> x; 
    } 
} 

타이밍을 : 관련

$ clang++ test_io.cpp -o test -O2 -std=c++11 
$ time ./test read < input 
real 0m2.802s 
user 0m2.780s 
sys 0m0.015s 
$ clang++ test_io.cpp -o test -O2 -std=c++11 -stdlib=libstdc++ 
clang: warning: libstdc++ is deprecated; move to libc++ 
$ time ./test read < input 
real 0m0.185s 
user 0m0.169s 
sys 0m0.012s 
+0

sync_with_stdio의 lib ++ 구현은 [src/ios.cpp] (http://llvm.org/svn/llvm-project/libcxx/trunk/src/ios.cpp) 끝에 있습니다. Joky가 말했듯이, 그것은 아무 작업도 아닙니다. –