我想用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
?
答案 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。我想我会将其发布到一个单独的问题中。