如何在 C++1z 中使用实验性并行 STL?

How to use experimental parallel STL in C++1z?

我想尝试 C++17 的并行 STL。但是,我在 libc++ 中找不到 experimental/execution_policy。我该如何尝试?

我正在尝试 http://en.cppreference.com/w/cpp/experimental/reduce,它说我应该包括这些文件,但我找不到 execution_policy。

#include <experimental/execution_policy>

我安装libc++后(我跟着http://libcxx.llvm.org/docs/BuildingLibcxx.html),我尝试了下面的命令,但没有成功。

$ clang++-3.5 -std=c++1z test.cpp -lc++experimental
test.cpp:5:10: fatal error: 'experimental/execution_policy' file not found
#include <experimental/execution_policy>
         ^
1 error generated.

这还没有实现吗?

Is this not implemented yet?

没错。并行 TS(将存在于 <experimental/xxx> 中)或(尚未最终确定的)C++1z 标准中的并行算法都没有在 libc++ 中实现(尚未)。

我在Intel 18 Parallel Studio XE beta, which composes with both libc++ and libstdc++ and is based on TBB中使用了PSTL的实现。我已经测试了 for_eachtransform 但没有其他测试。

更新:英特尔 PSTL 是 open-source (https://github.com/intel/parallelstl) 并与 GCC 和 Clang 一起工作。

更新 2:Intel PSTL 是 GCC 9.1 (release notes, commit) and LLVM (commit) 的一部分。

因为对 PSTL 的支持并不普遍,我通过预处理器使 code 可移植:

#if defined(USE_PSTL) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1800)
  std::for_each( pstl::execution::par, std::begin(range), std::end(range), [&] (int i) {
    std::for_each( pstl::execution::par_unseq, std::begin(range), std::end(range), [&] (int j) {
#elif defined(USE_PSTL) && defined(__GNUC__) && defined(__GNUC_MINOR__) \
                        && ( (__GNUC__ == 8) || (__GNUC__ == 7) && (__GNUC_MINOR__ >= 2) )
  __gnu_parallel::for_each( std::begin(range), std::end(range), [&] (int i) {
    __gnu_parallel::for_each( std::begin(range), std::end(range), [&] (int j) {
#else
#warning Parallel STL is NOT being used!
  std::for_each( std::begin(range), std::end(range), [&] (int i) {
    std::for_each( std::begin(range), std::end(range), [&] (int j) {
#endif
        B[i*order+j] += A[j*order+i];
        A[j*order+i] += 1.0;
      });
    });
  }

你可以看到这段代码是基于 Mac 上的 libc++,虽然 PSTL 部分本身来自 Intel headers,后者又使用 TBB 作为运行时。

$ otool -L transpose-vector-pstl
transpose-vector-pstl:
    @rpath/libtbb.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.5.0)
    @rpath/libiomp5.dylib (compatibility version 5.0.0, current version 5.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

完全披露:我在 Intel 工作,并与开发人员讨论了此实现,但我对此不承担任何责任。

Jeff 的回答进一步...

GCC 和 Clang 现在都包含英特尔 PSTL 实现,以便在其 C++ 标准库中提供 C++17 并行算法。

在撰写本文时,还有对英特尔 TBB 库的额外依赖,PSTL 将其用作后端以提供并行性。