如何在循环中使用所有核心?

Ufx*_*Ufx 6 c++ multithreading c++11 c++14 c++17

有一个循环.

for (int i = 0; i < n; ++i) {
    //...
    v[i] = o.f(i);
    //...
}
Run Code Online (Sandbox Code Playgroud)

每个v[i] = o.f(i)都独立于所有其他v[i] = o.f(i).
n可以是任何值,也可以不是核心数的倍数.使用所有核心执行此操作的最简单方法是什么?

Cal*_*eth 6

为此目的存在ExecutionPolicy算法的重载<algorithm>.std::transform将函数应用于源范围的每个元素以分配给目标范围.

v.begin()是一个可接受的目的地,只要v具有适当的大小.您的代码段在使用时会假定它v[i],所以我也会这样做.

然后我们需要一个迭代器,它将值[0, n)作为我们的源,所以boost::counting_iterator<int>.

最后,我们需要一个Callable适用o.f于我们的值的东西,所以让我们o在lambda中捕获.

#include <algorithm>
#include <execution>
#include <boost/iterator/counting_iterator.hpp>

// assert(v.size() >= n)
std::transform(std::execution::par, boost::counting_iterator<int>(0), boost::counting_iterator<int>(n), v.begin(), [&o](int i){ return o.f(i); });
Run Code Online (Sandbox Code Playgroud)

如果o.f不执行任何"矢量化 - 不安全操作",您可以使用std::execution::par_unseq,它可以在同一个线程上交错调用(即展开循环并使用SIMD指令)