使用OpenMP线程重新初始化向量要快得多吗?

时间:2016-04-24 09:53:38

标签: c++ multithreading openmp

我使用OpenMP库进行并行计算。我使用C ++向量,其大小通常为1 * 10 ^ 5。在进行迭代过程时,我需要将一堆这些大型向量(不是线程私有但全局范围)重新初始化为初始值。这是更快的方法吗?使用#pragma omp或#pragma omp single?

2 个答案:

答案 0 :(得分:1)

假设原始数据类型的简单初始化,初始化本身将受内存或缓存带宽的约束。但是,在现代系统上,您必须使用多个线程来充分利用内存和缓存带宽。例如,看看these benchmark results,其中前两行比较并行与单线程缓存,最后两行是并行与单线程主内存带宽。在面向高性能的系统上,特别是对于多个套接字,更多线程对于利用可用带宽非常重要。

但是,重新初始化的性能并不是您应该关心的唯一事情。假设例如双精度浮点数,10e5元素等于800 kb内存,适合缓存。为了提高整体性能,您应该尝试确保在初始化之后,数据位于靠近核心的高速缓存中,以便以后访问数据。在NUMA系统中(多个插槽具有更快的内存访问本地内存),这一点更为重要。

如果您同时初始化共享内存,请确保不要从不同的内核写入相同的缓存行,并尝试保持访问模式的正常性,以免混淆预取程序和CPU的其他聪明魔法

一般建议是:从一个简单的实现开始,然后分析您的应用程序,以了解瓶颈的实际位置。不要投资复杂,难以维护,特定于系统的优化,这些优化可能只会影响整个运行时代码的微小部分。如果事实证明这是您的应用程序的瓶颈,并且您的硬件资源利用率不高,那么您需要了解底层硬件(本地/共享缓存,NUMA,预取程序)的性能特征并相应地调整您的代码。 / p>

答案 1 :(得分:0)

一般的答案需要是“它取决于你必须衡量”,因为根据类型,C ++中的初始化可能是微不足道的或非常昂贵的。你没有提供太多细节,所以不得不猜测一下 如果一个类有一个计算成本很高的构造函数,并行工作可能非常值得。

您的具体措辞“初始化为值”表示您的向量包含POD(例如,整数?)。我会假设情况就是这样。

假设这样,并行化几乎肯定会更快。此操作受内存带宽的限制,一个CPU线程应该能够将内存带宽饱和到大约99%。

然而,由于几个原因(我不打算详细说明,足够说它不太可能更快),并行化很可能会变慢。