gpt4 book ai didi

c++ - VC++ : Performance drop x20 when more threads than cpus but not under g++

转载 作者:可可西里 更新时间:2023-11-01 16:32:32 25 4
gpt4 key购买 nike

简单的多线程 c++11 程序,其中所有线程在紧密循环中锁定相同的互斥量。

当它使用8个线程时(作为逻辑cpu的数量)可以达到500万锁/秒

但是只添加一个额外的线程 - 性能会下降到 200,000/秒!

编辑:

在 g++4.8.2 (ubuntu x64) 下:即使有 100 个线程,性能也不会下降!(性能是两倍多,但那是另一回事了) - 所以这似乎确实是一个特定于 VC++ 互斥实现的问题

我用下面的代码(Windows 7 x64)复制了它:

#include <chrono>
#include <thread>
#include <memory>
#include <mutex>
#include <atomic>
#include <sstream>
#include <iostream>

using namespace std::chrono;

void thread_loop(std::mutex* mutex, std::atomic_uint64_t* counter)
{
while (true)
{
std::unique_lock<std::mutex> ul(*mutex);
counter->operator++();
}
}

int _tmain(int argc, _TCHAR* argv[])
{

int threads = 9;
std::mutex mutex;
std::atomic_uint64_t counter = 0;

std::cout << "Starting " << threads << " threads.." << std::endl;
for (int i = 0; i < threads; ++i)
new std::thread(&thread_loop, &mutex, &counter);

std::cout << "Started " << threads << " threads.." << std::endl;
while (1)
{
counter = 0;
std::this_thread::sleep_for(seconds(1));
std::cout << "Counter = " << counter.load() << std::endl;
}
}

VS 2013 分析器告诉我,大部分时间 (95.7%) 都浪费在一个紧密的循环中(rtlocks.cpp 中的第 697 行):

while (IsBlocked() & & spinWait._SpinOnce())
{
//_YieldProcessor is called inside _SpinOnce
}

可能是什么原因?如何改进?

操作系统:windows 7 x64

CPU:i7 3770 4 核(x2 超线程)

最佳答案

如果有 8 个线程,您的代码会旋转,但无需 CPU 在线程失去其时间片之前挂起线程即可获得锁。

随着您添加越来越多的线程,争用级别会增加,因此线程无法在其时间片内获取锁的机会也会增加。当发生这种情况时,线程被挂起并且另一个线程发生上下文切换,CPU 将检查该线程是否可以被唤醒。

所有这些切换、挂起和唤醒都需要从用户模式转换到内核模式,这是一个昂贵的操作,因此性能会受到显着影响。

为了改进,要么减少争用锁的线程数量,要么增加可用内核的数量。在您的示例中,您使用的是 std::atomic 编号,因此您无需锁定即可对其调用 ++,因为它已经是线程安全的.

关于c++ - VC++ : Performance drop x20 when more threads than cpus but not under g++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21255311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com