在我的应用程序中,我有一个for循环,运行大约1000万个项目,如下所示:
int main(int argc, char* argv [])
{
unsigned int nNodes = 10000000;
Node** nodeList = new Node* [nNodes];
initialiseNodes(nodeList); // nodes are initialised here
for (unsigned int ii = 0l ii < nNodes; ++ii)
nodeList[ii]->update();
showOutput(nodeList) // show the output in some way
}我不会详细介绍节点是如何准确初始化或显示的。重要的是,Node::update()方法是一个小方法,独立于其他节点。因此,并行执行此for循环将是非常有利的。因为这只是一件小事,所以这次我想远离OpenCL/CUDA/OpenMP,所以我使用了C++ Concurrency::parallel_for。那么代码看起来就像这样:
#include <ppl.h>
int main(int argc, char* argv [])
{
unsigned int nNodes = 10000000;
Node** nodeList = new Node* [nNodes];
initialiseNodes(nodeList); // nodes are initialised here
Concurrency::parallel_for(unsigned int(0), nNodes, [&](unsigned int ii) {
nodeList[ii]->update();
});
showOutput(nodeList) // show the output in some way
}我发现,这确实让程序速度提高了一点,但通常只有20%左右。坦率地说,我期望更多。谁能告诉我这是不是使用parallel_for时的典型加速因素?或者,有没有方法可以让它发挥更大的作用(而不用切换到GPU实现)?
发布于 2012-09-27 01:40:15
在一个问题上投入更多的核心并不总是会带来改进。事实上,在最坏的情况下,它甚至会降低性能。能否从使用多核中获益取决于很多因素,例如所涉及的共享数据量。有些问题本质上是可并行化的,有些则不是。
发布于 2012-10-23 20:26:54
我发现我认为对性能提升贡献最大的是什么。当然,就像@anthony-burleigh说的那样,任务必须是可并行的,共享数据的影响也是如此。然而,我发现并行化方法的计算负载要重要得多。大任务似乎比小任务有更高的速度。
因此,例如,在:
Concurrency::parallel_for(unsigned int(0), nNodes, [&](unsigned int ii) {
nodeList[ii]->update(); // <-- very small task
});我只得到了1.2倍的加速因子。但是,在繁重的任务中,例如:
Concurrency::parallel_for(unsigned int(0), nNodes, [&](unsigned int ii) {
ray[ii]->recursiveRayTrace(); // <-- very heavy task
});程序的运行速度突然提高了3倍。
我相信这一切都有更深层次的解释,但这是我通过试验和错误发现的。
https://stackoverflow.com/questions/12607216
复制相似问题