joz*_*yqk 5 c c++ windows multithreading critical-section
我正在将一些代码移植到Windows,发现线程非常慢.Windows上的任务需要300秒(两个至强E5-2670 8核2.6ghz = 16核)和3.5秒(xeon E5-1607 4核3ghz).使用vs2012 express.
我有32个线程全部调用EnterCriticalSection(),弹出std :: stack的80字节作业,LeaveCriticalSection并做一些工作(总共250k个工作).
在每个关键部分调用之前和之后,我打印线程ID和当前时间.
(大致相同的Debug/Release,Debug需要更长的时间.我希望能够正确分析代码:P)
注释掉作业调用会使整个过程花费2秒钟(仍然超过linux).
我已经尝试了queryperformancecounter和timeGetTime,两者都给出了大致相同的结果.
AFAIK这个工作永远不会进行任何同步调用,但我不能解释减速,除非它确实如此.
我不知道为什么从堆栈复制并调用pop需要这么长时间.另一个令人困惑的事情是为什么对leave()的调用需要这么长时间.
任何人都可以推测为什么它运行如此缓慢?
我不会想到处理器的差异会带来100倍的性能差异,但它可能与双CPU有关吗?(必须在不同于内部核心的CPU之间进行同步).
顺便说一句,我知道std :: thread,但希望我的库代码能够与pre 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);
Run Code Online (Sandbox Code Playgroud)
和mutex类,删除linux #ifdef的东西......
CRITICAL_SECTION mutex;
...
Mutex::Mutex()
{
InitializeCriticalSection(&mutex);
}
Mutex::~Mutex()
{
DeleteCriticalSection(&mutex);
}
void Mutex::lock()
{
EnterCriticalSection(&mutex);
}
void Mutex::unlock()
{
LeaveCriticalSection(&mutex);
}
Run Code Online (Sandbox Code Playgroud)
看来您的 Windows 线程正面临超级争用。它们看起来完全是连续的。您的临界区有大约 7 毫秒的总处理时间和 32 个线程。如果所有线程都在锁上排队,队列中的最后一个线程只有在休眠大约 217 毫秒后才能运行。这与您观察到的 160 毫秒等待时间相差不远。
因此,如果线程除了进入临界区之外没有其他事情可做,执行工作,然后离开临界区,这就是我期望的行为。
尝试表征 linux 分析行为,并查看程序行为是否确实进行同类比较。