线程获得的收益远低于预期 - 为什么?

时间:2014-04-08 16:38:24

标签: c++ multithreading c++11 lambda

我的功能评估有点慢。我试图通过使用线程加快速度,因为有三件事可以并行完成。

是单线程版本
return dEdx_short(E) + dEdx_long(E) + dEdx_quantum(E);

这些函数的评估分别需要〜250us,~250us和~100us。所以我实现了一个三线程解决方案:

double ret_short, ret_long, ret_quantum; // return values for the terms

auto shortF = [this,&E,&ret_short] () {ret_short = this->dEdx_short(E);};
std::thread t1(shortF);
auto longF = [this,&E,&ret_long] () {ret_long = this->dEdx_long(E);};
std::thread t2(longF);
auto quantumF = [this,&E,&ret_quantum] () {ret_quantum = this->dEdx_quantum(E);};
std::thread t3(quantumF);

t1.join();
t2.join();
t3.join();

return ret_short + ret_long + ret_quantum;

我预计需要大约300us,但它实际需要大约600us - 与单线程版本基本相同!这些本质上都是线程安全的,所以没有等待锁。我检查了我的系统上的线程创建时间,它是〜25us。我没有使用我的所有核心,所以我有点困惑的是为什么并行解决方案如此之慢。这与lambda创作有关吗?

我试图绕过lambda,例如:

std::thread t1(&StopPow_BPS::dEdx_short, this, E, ret_short);

重写被调用的函数后,但这给了我一个错误attempt to use a deleted function ...

1 个答案:

答案 0 :(得分:1)

也许您遇到了false sharing。要进行验证,请将返回值存储在使用整个缓存行的类型中(大小取决于CPU)。

const int cacheLineSize = 64; // bytes
union CacheFriendly
{
    double value;
    char dummy[cacheLineSize];
} ret_short, ret_long, ret_quantum; // return values for the terms
// ...