2016-10-29 64 views
3

Q極其緩慢的輸入/輸出:是否可以在OS X,以改善此代碼LLVM鏘的IO: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; 
    } 
    } 
} 

編譯:

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 

除了可悲的事實,10MB的文件閱讀成本3秒,這是除G慢 ++(通過自制安裝):

> 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)。從自制軟件(3.7和3.8)安裝的clang也會產生緩慢的io。安裝在Ubuntu(3.8)上的clang生成快速io。 Apple LLVM version 8.0.0生成緩慢的IO(2人問)。

我也dtrussed有點(sudo dtruss -c "./test_io gen | ./test_io read"),發現鐺版本使得2686個write_nocancel系統調用,而gcc版本使得2079個writev系統調用。這可能指向問題的根源。

+0

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

+0

您是否嘗試過-O3 – Danh

+0

如果您將來自clang編譯版本的輸出提供給gcc編譯版本,它仍然非常快,但是如果將gcc編譯版本提供給clang編譯版本,它會變慢 - 所以我推斷它是鏗鏘聲慢的讀數。如果您將從空間輸出的字符更改爲「X」,則它們都快並且速度相同。 –

回答

3

問題出在libC++中,它沒有實現sync_with_stdio。

您的命令行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所說的那樣,這是一個無用的工具。 –