windows - Windows 上的线程创建速度慢

标签 windows multithreading c++11

我已经使用 C++11 工具将数字运算应用程序升级为多线程程序。它在 Mac OS X 上运行良好,但无法从 Windows (Visual Studio 2013) 上的多线程中获益。使用以下玩具程序

#include <iostream>
#include <thread>

void t1(int& k) {
    k += 1;
};

void t2(int& k) {
    k += 1;
};

int main(int argc, const char *argv[])
{
    int a{ 0 };
    int b{ 0 };

    auto start_time = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 10000; ++i) {
        std::thread thread1{ t1, std::ref(a) };
        std::thread thread2{ t2, std::ref(b) };
        thread1.join();
        thread2.join();
    }
    auto end_time = std::chrono::high_resolution_clock::now();
    auto time_stack = std::chrono::duration_cast<std::chrono::microseconds>(
        end_time - start_time).count();
    std::cout << "Time: " << time_stack / 10000.0 << " micro seconds" <<
        std::endl;

    std::cout << a << " " << b << std::endl;

    return 0;
}

我发现在 Mac OS X 上启动一个线程需要 34 微秒,而在 Windows 上则需要 340 微秒。我在 Windows 方面做错了什么吗?是编译器问题吗?

最佳答案

不是编译器问题(严格来说也不是操作系统问题)。

众所周知,创建线程是一项昂贵的操作。这在 Windows 下是尤其是(在 clone 之前在 Linux 下也是如此)。
此外,创建和加入线程必然很慢,并且不能说明创建线程本身。加入假定线程已经退出,这只能在它被安排运行之后发生。因此,您的测量包括调度引入的延迟。就目前而言,您测量的时间实际上相当好(它们很容易长 20 倍!)。

然而,生成线程是否慢并不重要。

真实程序中像您的基准测试那样创建 20,000 个线程是一个严重的错误。虽然创建数千(甚至数百万)个线程并非严格违法或不允许,但使用线程的“正确”方式是创建的线程数不超过大约 CPU 内核数。也不会一直创建生命周期非常短的线程。
可能有一些短暂的线程,并且您可能创建一些额外的线程(例如阻塞 I/O),但您不会想要创建数百个或数以千计的这些。每增加一个线程(超出 CPU 内核的数量)就意味着更多的上下文切换、更多的调度程序工作、更多的缓存压力,以及每个线程 1MB 的地址空间和 64kB 的物理内存(由于堆栈保留和提交粒度)。

现在,假设您在程序启动时创建了 10 个线程,总共是否需要 3 毫秒根本无关紧要。无论如何,程序启动需要几百毫秒(至少),没有人会注意到差异。

关于windows - Windows 上的线程创建速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27057713/

相关文章:

c++ - std::this_thread::yield 只是一个提示会不会有问题?

c++ - 模板函数采用任何仿函数并返回仿函数返回的类型

windows - 如何从 .cer 和 .key 获取 .pfx 文件?

windows - 从 Windows 上的同一对话框中选择文件或文件夹?

c++ - 花括号和圆括号之间的参数评估顺序

c - 打印传递给 pthread_create 的参数

java - Android - 在单独的线程上进行 HTTP GET

c++ - 如何最好地将 VARIANT_BOOL 转换为 C++ bool?

c++ - SendMessage 总是返回零?

Java 多线程无法正常工作