与ppl或OpenMP相比,使用boost::thread可以获得更好的并行任务性能
Parallel tasks get better performances with boost::thread than with ppl or OpenMP
我有一个可以并行化的c++程序。我用的是Visual Studio 2010, 32位编译。
简而言之,程序的结构如下
#define num_iterations 64 //some number
struct result
{
//some stuff
}
result best_result=initial_bad_result;
for(i=0; i<many_times; i++)
{
result *results[num_iterations];
for(j=0; j<num_iterations; j++)
{
some_computations(results+j);
}
// update best_result;
}
由于每个some_computations()
都是独立的(读取一些全局变量,但没有修改全局变量),因此我并行化了内部for
-循环。
我的第一次尝试是boost::thread,
thread_group group;
for(j=0; j<num_iterations; j++)
{
group.create_thread(boost::bind(&some_computation, this, result+j));
}
group.join_all();
结果很好,但我决定再试一次。
我尝试了OpenMP库
#pragma omp parallel for
for(j=0; j<num_iterations; j++)
{
some_computations(results+j);
}
结果比boost::thread
的结果差。
parallel_for()
:
Concurrency::parallel_for(0,num_iterations, [=](int j) {
some_computations(results+j);
})
结果是最差的。
我发现这种行为非常令人惊讶。由于OpenMP和ppl是为并行化而设计的,所以我期望得到比boost::thread
更好的结果。我错了吗?
为什么boost::thread
给我更好的结果?
OpenMP或PPL不做悲观的事情。它们只是按照要求去做,但是当你尝试并行循环时,你应该考虑一些事情。
如果没有看到你是如何实现这些事情的,就很难说真正的原因是什么。
同样,如果每个迭代中的操作都依赖于同一循环中的任何其他迭代,那么这将产生争用,这将减慢速度。您还没有显示some_operation
函数的实际功能,因此很难判断是否存在数据依赖关系。
一个可以真正并行化的循环必须能够让每个迭代完全独立于所有其他迭代运行,在任何迭代中都不访问共享内存。所以最好是把内容写入局部变量,然后在最后进行复制。
不是所有的循环都可以并行化,这取决于所做的工作的类型。
例如,在屏幕缓冲区的每个像素上完成的工作对并行化很有好处。每个像素都完全独立于所有其他像素,因此,线程可以在循环的一次迭代中完成工作,而不需要在迭代之间的循环中等待共享内存或数据依赖。
同样,如果你有一个连续的数组,这个数组可能部分在缓存行,如果你在线程a中编辑元素5,然后在线程B中修改元素6,你可能会得到缓存争用,这也会减慢速度,因为它们会驻留在同一个缓存行中。虚假分享。
在进行循环并行化时需要考虑很多方面。
简而言之,openMP
主要基于共享内存,有额外的任务管理和内存管理成本。ppl
是为了处理通用数据结构和算法的通用模式而设计的,它带来了额外的复杂性成本。它们都有额外的CPU成本,但你的boost
线程没有(boost
线程只是简单的API包装)。这就是为什么它们都比boost
版本慢的原因。并且,由于示例计算彼此独立,没有同步,openMP
应该接近boost
版本。
它出现在简单的场景中,但是,对于复杂的场景,具有复杂的数据布局和算法,它应该与上下文相关。
- 哪种方法更好,性能明智
- Msgpack能否提供更好的性能和与Python的struct.pack()相同的功能?
- 静态常量与常量局部变量,哪一个性能更好
- 在 C++ 中使用 OpenMP 并行化两个 for 循环不会提供更好的性能
- 为什么 C++ 代码实现的性能不比 python 实现更好?
- 如何通过更好的性能传递和共享共享的所有权
- 牢记干净的代码的性能,什么更好
- MongoC ++驱动程序BSON构造:基于流与基于字符串解析.哪一个性能更好?
- 是否有更好的方法(性能提高 /内置功能)获得矩形的旋转角度
- 对于阵列复制,const&的性能更好吗?
- 将中间变量用于三元运算符(或类似运算符)以获得更好的性能
- 全局对象是否提供比多个本地实例更好的性能
- 我们是否应该将指向类实例的智能指针存储在大型 std::vector 中以获得更好的性能?
- C++程序在管道传输时性能更好
- 在OpenGL中为顶点、uvs和法线使用一个缓冲区是否比使用三个缓冲区性能更好
- 性能权衡-MATLAB何时比C/C++更好/更慢
- 如何利用STL在本期中获得更好的结果和性能
- 哪一个性能更好:使用函数或精确代码
- (开放式简历拼接)如何使用OpenCV Stitcher类获得更好的性能
- 将所有双精度转换为整数以获得更好的性能,这只是一个谣言