LLVM Clang在OS X上产生极慢的输入/输出

时间:2016-10-29 12:20:04

标签: c++ macos llvm llvm-clang

问:在OS X下使用LLVM Clang是否可以改进此代码的IO:

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秒钟,它比(通过自制软件安装)慢

> 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人问)。

我也稍微讨论了一下(sudo dtruss -c "./test_io gen | ./test_io read")并发现clang版本制作了2686 write_nocancel个系统调用,而gcc版本制作了2079个writev系统调用。这可能指出了问题的根源。

1 个答案:

答案 0 :(得分: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