c++ - 从线程中获得的 yield 远低于预期 - 为什么?

标签 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...

最佳答案

也许您正在经历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
// ...

关于c++ - 从线程中获得的 yield 远低于预期 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22943140/

相关文章:

c++ - 在不同范围的结构之间转换

java - 如何在 JNI 中将 int 转换为 String(?)?

c++ - Qt - 同步线程不工作 - 线程停止但实际上没有停止,有时在不应该的时候停止

c++ - "E"在C++11标准 "ISO/IEC 14882:2011(E)"的名称中代表什么

c++ - 线程中 OpenCv 3.2.0 的内存泄漏

c++ - size_t 的大小是否始终等于 void * 的大小

c++ - 为什么 std::bitset<8> 变量无法处理 11111111?

python - 以周期性间隔记录无限数据

c# - 如何测量 .NET 中多个并发线程的代码块(线程)执行时间

c++ - 如何从 cin 获取用户输入到 C++11 std::array