我已经构建了一个C ++代码而没有想到我以后需要多线程化它。我现在已经使用openMP多线程化了3个主循环。以下是性能比较(使用bash中的time
衡量)
单线程
real 5m50.008s
user 5m49.072s
sys 0m0.877s
多线程(24个线程)
real 1m22.572s
user 28m28.206s
sys 0m4.170s
使用24核将实时时间缩短了4.24倍。当然,我没想到代码的速度要快24倍。我真的不知道实际上会发生什么。
- 是否有一条经验法则可以让人们预测,与单个线程相比,使用n
线程运行给定代码的速度会快多少?
- 是否有提高多线程流程性能的一般提示?
答案 0 :(得分:2)
我相信你知道显而易见的障碍成本。但是很难在琐碎的东西和对某人有帮助的东西之间划清界线。以下是从使用中吸取的一些经验教训,如果我想到更多,我会添加它们:
总是尝试尽可能长时间使用线程私有变量,考虑即使是减少,也只提供少量的集体结果。
首选并行运行长段代码和长并行段(#pragma omp parallel ... #pragma omp for
),而不是单独并行化循环(#pragma omp parallel for
)。
不要并行化短循环。在二维迭代中,通常足以并行化外循环。如果使用collapse
对整个事物进行并行化,请注意OpenMP将线性化它,引入融合变量并单独访问索引会产生开销。
使用线程私有堆。尽可能避免共享池和集合,即使不同的线程可以独立访问集合的不同成员。
描述您的代码,看看在忙碌的等待和可能发生的地方花了多少时间。
了解使用不同计划策略的后果。尝试一下更好,不要假设。
如果您使用关键部分,请为其命名。所有未命名的CS都必须互相等待。
如果您的代码使用随机数,请使其可重现:定义线程局部RNG,以可控方式对所有内容进行种子化,对减少强制执行命令。确定性地进行基准测试,而不是统计上的。
在Stack Overflow上浏览类似的问题,例如,精彩的答案here。