我正在运行一个非常沉重但非常平行的算法。
我一直在寻找加速它的方法,我注意到我的最慢操作是我的VecAdd功能(它在6000左右的宽矢量上被调用了数千次)。
实施如下:
bool VecAdd( float* pOut, const float* pIn1, const float* pIn2, unsigned int num )
{
for( int idx = 0; idx < num; idx++ )
{
pOut[idx] = pIn1[idx] + pIn2[idx];
}
return true;
}
它是一个非常简单的循环,但所有添加都可以并行执行。我的第一个优化选项是转移到使用SIMD,因为我可以轻松地将速度提高近4倍。
然而,我也对使用OpenMP并让它自动为for循环进行线程化的可能性感兴趣(可能会给我一个4倍的加速,总共16x的SIMD)。
然而它确实运行缓慢。循环完成后,处理我的示例数据大约需要3.2秒。如果我插入
#pragma omp parallel for
在for循环之前的我假设它会将几个添加块添加到其他线程中。
不幸的是,结果是处理我的示例数据需要大约7秒钟。
现在我明白我的很多问题都是由设置线程等的开销造成的,但我仍然感到惊讶的是它运行的速度有多慢。
是否有可能通过某种方式提前设置线程池来加快速度,或者我永远无法对抗这些开销?
关于我是否可以使用OpenMP很好地解决这些建议的任何想法都将非常感谢!
答案 0 :(得分:4)
你的循环应与#pragma omp parallel for并行化。 但是,我认为问题在于您不应该在该级别进行并行化。你说这个函数被调用数千次,但只能运行6000个浮点数。在更高级别进行并行化,以便每个线程负责对VecAdd的thounsands / 4调用。现在你有这个算法:
更改它,使其在最高级别平行。
内存带宽当然很重要,但它不会导致比串行执行慢。