改进多线程的一般技巧(用C ++编写)

时间:2016-12-05 21:52:03

标签: c++ multithreading performance prediction

我已经构建了一个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线程运行给定代码的速度会快多少?

- 是否有提高多线程流程性能的一般提示?

1 个答案:

答案 0 :(得分:2)

我相信你知道显而易见的障碍成本。但是很难在琐碎的东西和对某人有帮助的东西之间划清界线。以下是从使用中吸取的一些经验教训,如果我想到更多,我会添加它们:

  • 总是尝试尽可能长时间使用线程私有变量,考虑即使是减少,也只提供少量的集体结果。

  • 首选并行运行长段代码和长并行段(#pragma omp parallel ... #pragma omp for),而不是单独并行化循环(#pragma omp parallel for)。

  • 不要并行化短循环。在二维迭代中,通常足以并行化外循环。如果使用collapse对整个事物进行并行化,请注意OpenMP将线性化它,引入融合变量并单独访问索引会产生开销。

  • 使用线程私有堆。尽可能避免共享池和集合,即使不同的线程可以独立访问集合的不同成员。

  • 描述您的代码,看看在忙碌的等待和可能发生的地方花了多少时间。

  • 了解使用不同计划策略的后果。尝试一下更好,不要假设。

  • 如果您使用关键部分,请为其命名。所有未命名的CS都必须互相等待。

  • 如果您的代码使用随机数,请使其可重现:定义线程局部RNG,以可控方式对所有内容进行种子化,对减少强制执行命令。确定性地进行基准测试,而不是统计上的。

  • 在Stack Overflow上浏览类似的问题,例如,精彩的答案here