簡體   English   中英

與簡單地創建線程相比,使用線程池是否有性能優勢?

[英]Is there a performance benefit in using a pool of threads over simply creating threads?

我想知道與簡單地創建線程並允許操作系統對它們進行排隊和調度相比,使用線程池是否有性能優勢。

假設我有 20 個可用線程,並且我有 60 個要在這些線程上運行的任務,比如說我有類似的東西;

void someTask() {

  //...performs some task

}

// say std::thread::hardware_concurrency() = 20

std::vector<std::thread> threads;
for (int i = 0; i < 60; i++) {
  threads.push_back(std::thread(someFunc));
}

std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});

相反,創建一個具有 20 個線程的池並在線程空閑時為每個線程分配另一個“任務”是否有好處? 我假設生成線程有一些開銷,但是為這樣的問題創建池還有其他好處嗎?

創建一個線程通常需要 75k 周期(~20us)。

啟動所述線程可能需要 200k 周期(~60us)。

喚醒一個線程大約需要 15k 個周期(~5us)。

因此,您可以看到值得預先創建線程並喚醒它們而不是每次都創建線程。

#include <iostream>
#include <thread>
#include <cstdint>
#include <mutex>
#include <chrono>
#include <condition_variable>

uint64_t now() {
    return __builtin_ia32_rdtsc();
}

uint64_t t0 = 0;
uint64_t t1 = 0;
uint64_t t2 = 0;
uint64_t t3 = 0;
uint64_t t4 = 0;
double sum01 = 0;
double sum02 = 0;
double sum34 = 0;
uint64_t count = 0;
std::mutex m;
std::condition_variable cv;

void run() {
    t1 = now();
    cv.notify_one();
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk);
    t4 = now();
}

void create_thread() {
    t0 = now();
    std::thread th( run );
    t2 = now();
    std::this_thread::sleep_for( std::chrono::microseconds(100));
    t3 = now();
    cv.notify_one();
    th.join();
    count++;
    sum01 += (t1-t0);
    sum02 += (t2-t0);
    sum34 += (t4-t3);
}

int main() {
    const uint32_t numloops = 10;
    for ( uint32_t j=0; j<numloops; ++j ) {
        create_thread();
    }
    std::cout << "t01:" << sum01/count << std::endl;
    std::cout << "t02:" << sum02/count << std::endl;
    std::cout << "t34:" << sum34/count << std::endl;
}

典型結果:

Program returned: 0
t01:64614.4
t02:54655
t34:15758.4

資料來源: https://godbolt.org/z/recfjKe8x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM