如何在 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_each
和 transform
但没有其他测试。
更新:英特尔 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 将其用作后端以提供并行性。
我想尝试 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_each
和 transform
但没有其他测试。
更新:英特尔 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 将其用作后端以提供并行性。