gpt4 book ai didi

c++ - 用零并行填充 std::vector

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:12 31 4
gpt4 key购买 nike

我要填写一个std::vector<int>零与 openmp。如何快速做到这一点?

我听说循环遍历 vector 以将每个元素设置为零很慢,而且 std::fill快多了。现在还是这样吗?

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

我必须手动划分 std::vector<int> 吗?进入区域,使用 #pragma omp for遍历每个线程,然后使用 std::fill在循环中?

最佳答案

您可以将 vector 拆分为每个线程要填充的 block 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)来进一步改进它。假设 v.data() 的对齐方式类似。这样,您就可以避免任何虚假共享问题。

在双插槽 24 核 Haswell 系统上,我获得了接近 9 倍的加速:1 个线程为 3.6 秒,24 个线程为 0.4 秒,4.8B ints = ~48 GB/s,结果略有不同这不是科学分析。但它与系统的内存带宽相距不远。

对于一般性能,您应该注意不仅针对此操作划分 vector ,而且如果可能的话,对于进一步的操作(无论是读还是写)也应以相同的方式划分。这样,如果需要,您就增加了数据实际上在缓存中的机会,或者至少在同一个 NUMA 节点上。

奇怪的是,在我的系统上 std::fill(..., 1);std::fill(..., 0) 快单个线程,但 24 个线程速度较慢。都使用 gcc 6.1.0 和 icc 17.0.1。我想我会把它发布到一个单独的问题中。

关于c++ - 用零并行填充 std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42044956/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com