【发布时间】:2013-03-04 16:38:00
【问题描述】:
我有一个可以并行化的 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 的差。
然后我尝试了 ppl 库并使用了parallel_for():
Concurrency::parallel_for(0,num_iterations, [=](int j) {
some_computations(results+j);
})
结果是最差的。
我发现这种行为非常令人惊讶。由于 OpenMP 和 ppl 是为并行化而设计的,因此我希望得到比 boost::thread 更好的结果。我错了吗?
为什么boost::thread 会给我更好的结果?
【问题讨论】:
-
能否请您量化“更好”,例如提供执行时间与线程数?使用
boost::thread,您将创建 64 个线程。 OpenPM 使用一组工作线程,其数量默认为虚拟 CPU 的数量。 PPL 也使用了线程池,而且开销甚至比 OpenMP 更高,因为它还实现了工作平衡。 -
我每次尝试都使用相同的数字(32 或 64),也许正如您所指出的,使用 OpenMP 和 ppl 将线程数设置为内核数可以获得更好的结果。我会试试的。
-
现在几乎不可能回答这个问题。
some_computations在做什么?我在某个地方可能存在争用(这可能会以不同的方式影响不同的库,例如,如果 openmp 实际上具有较低的开销,但是您对共享缓存线有很多写入,那么由此产生的缓存失效狂热实际上可能会使其变慢)?运行每个变体的并行块需要多长时间
标签: c++ openmp boost-thread ppl