并行填充std :: vector为零

时间:2017-02-04 20:00:07

标签: c++ vector parallel-processing openmp

我想用openmp填充std::fill为零。如何快速完成?

我听说循环遍历向量以将每个元素设置为零很慢,而std::vector<int>要快得多。现在还是这样吗?

Fastest way to reset every value of std::vector<int> to 0

我是否必须手动将#pragma omp for划分为多个区域,在每个线程上使用std::fill循环,然后在循环中使用spark.hadoop.fs.s3.maxRetries=20

1 个答案:

答案 0 :(得分:5)

您可以将矢量拆分为每个要填充std::fill的线程的块:

#pragma omp parallel
{   
    auto tid = omp_get_thread_num();
    auto chunksize = v.size() / omp_get_num_threads();
    auto begin = v.begin() + chunksize * tid;
    auto end = (tid == omp_get_num_threads() -1) ? v.end() : begin + chunksize);
    std::fill(begin, end, 0);
}

您可以通过将chunksize四舍五入到最近的高速缓存行/内存字大小(128字节= 32 int s)来进一步改进它。假设v.data()的排列方式相似。这样,您就可以避免任何错误的共享问题。

在双插槽24核心Haswell系统上,我得到的速度接近9x:1个线程为3.6s,24个线程为0.4s,4.8B ints = ~48 GB / s,结果略有不同这不是科学的分析。但它离系统的内存带宽并不太远。

对于一般性能,您应该关注的是,不仅可以为此操作划分矢量,还可以在可能的情况下以相同的方式划分矢量(读取或写入)。这样,如果需要,可以增加数据在缓存中的实际可能性,或至少在同一个NUMA节点上。

奇怪的是,我的系统std::fill(..., 1);对于单个线程比std::fill(..., 0)快,但对于24个线程则慢。两者都使用gcc 6.1.0和icc 17.0.1。我想我会将其发布到一个单独的问题中。