c++ - 将线程移植到 Windows。关键部分非常慢

标签 c++ c windows multithreading critical-section

我正在将一些代码移植到 Windows 中,发现线程处理速度极慢。该任务在 Windows 上需要 300 秒(使用两个至强 E5-2670 8 核 2.6ghz = 16 核),在 Linux 上需要 3.5 秒(至强 E5-1607 4 核 3ghz)。使用 vs2012 express 。

我有 32 个线程都在调用 EnterCriticalSection(),弹出一个 std::stack 的 80 字节作业,LeaveCriticalSection 并做一些工作(总共 250k 个作业)。

在每次关键部分调用之前和之后,我都会打印线程 ID 和当前时间。

  • 单线程锁等待时间~160ms
  • 将作业从堆栈中弹出大约需要 3 毫秒
  • 调用 leave 需要大约 3 毫秒
  • 这项工作耗时约 1 毫秒

(调试/发布大致相同,调试需要更长的时间。我希望能够正确分析代码:P)

注释掉作业调用会使整个过程花费 2 秒(仍然比 linux 多)。

我已经尝试了 queryperformancecounter 和 timeGetTime,两者给出的结果大致相同。

据我所知,这项工作从不进行任何同步调用,但除非它进行,否则我无法解释速度变慢的原因。

我不知道为什么从堆栈复制和调用 pop 需要这么长时间。 另一个非常令人困惑的事情是为什么调用 leave() 需要这么长时间。

谁能猜出为什么它运行得这么慢?

我没想到处理器的差异会带来 100 倍的性能差异,但这可能与双 CPU 有任何关系吗? (必须在不同的 CPU 之间同步而不是在内部内核之间同步)。

顺便说一下,我知道 std::thread 但希望我的库代码能够与 C++11 之前的版本一起工作。

编辑

//in a while(hasJobs) loop...

EVENT qwe1 = {"lock", timeGetTime(), id};
events.push_back(qwe1);

scene->jobMutex.lock();

EVENT qwe2 = {"getjob", timeGetTime(), id};
events.push_back(qwe2);

hasJobs = !scene->jobs.empty();
if (hasJobs)
{
    job = scene->jobs.front();
    scene->jobs.pop();
}

EVENT qwe3 = {"gotjob", timeGetTime(), id};
events.push_back(qwe3);

scene->jobMutex.unlock();

EVENT qwe4 = {"unlock", timeGetTime(), id};
events.push_back(qwe4);

if (hasJobs)
    scene->performJob(job);

和互斥量类,删除了 linux #ifdef 内容...

CRITICAL_SECTION mutex;

...

Mutex::Mutex()
{
    InitializeCriticalSection(&mutex);
}
Mutex::~Mutex()
{
    DeleteCriticalSection(&mutex);
}
void Mutex::lock()
{
    EnterCriticalSection(&mutex);
}
void Mutex::unlock()
{
    LeaveCriticalSection(&mutex);
}

最佳答案

当您第一次进入时,窗口的 CRITICAL_SECTION 会在一个紧密的循环中旋转。它不会挂起调用 EnterCriticalSection 的线程,除非在自旋循环中经过了相当长的一段时间。因此,让 32 个线程争用同一个临界区会消耗并浪费大量 CPU 周期。尝试使用互斥锁(请参阅 CreateMutex)。

关于c++ - 将线程移植到 Windows。关键部分非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18442574/

相关文章:

c++ - Windows 中的 WH_JOURNALRECORD Hook (C++) - 从未调用过回调。

c - 函数取决于 C 中的数据类型

windows - 在 windows cmd yes/no 提示下自动有脚本输入 yes

c++ - 数组作为 C++ 中的输出参数

c++ - 从可变参数模板中读取参数

C 中能否将一个字符串的一部分复制到另一个字符串上?但复制的开始索引不为零

c - 海湾合作委员会 + C : Keeping Functions in order in the binary file

c - 如何从C中的内存映射文件读取bin文件(FAT16分区)?

windows - 是 C :\Users\Public\Documents writable to everyone by default? 中的目录吗

c++ - C++ 中的 std::memory_order 究竟提供了哪些栅栏?