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

Ale*_*x Z 7 c++ lambda multithreading c++11

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

return dEdx_short(E) + dEdx_long(E) + dEdx_quantum(E);
Run Code Online (Sandbox Code Playgroud)

这些函数的评估分别需要〜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;
Run Code Online (Sandbox Code Playgroud)

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

我试图绕过lambda,例如:

std::thread t1(&StopPow_BPS::dEdx_short, this, E, ret_short);
Run Code Online (Sandbox Code Playgroud)

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

D D*_*mmr 1

也许您正在经历虚假分享。要进行验证,请将返回值存储在使用整个缓存行的类型中(大小取决于 CPU)。

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

  • 不会 `union cache_Friendly { double value; 字符虚拟[CACHE_LINE_SIZE];};` 会更好吗? (2认同)