Печать в std :: cout внутри потоков заставляет их работать быстрее - PullRequest
0 голосов
/ 02 мая 2019

Чтобы проверить функцию async в C++, я создал следующий код:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <future>
#include <chrono>
using namespace std;

constexpr size_t numTasks = 32;
mutex ioMtx;                            // mutex for std::cout access

int getTen() {
    this_thread::sleep_for(std::chrono::seconds(1));
    return 10;
}

int getTenAndPrintThreadId() {
    {
        lock_guard<mutex> guard(ioMtx);
        cout << this_thread::get_id() << endl;
    }

    this_thread::sleep_for(std::chrono::seconds(1));
    return 10;
}

void runThreads(int (*getIntFn)(), string name) {
    int result = 0;
    auto start = chrono::high_resolution_clock::now();

    vector<future<int>> futures;
    futures.reserve(numTasks);
    for (int i = 0; i < numTasks; ++i) {
        futures.push_back(
            async(getIntFn)
        );
    }

    for (int i = 0; i < numTasks; ++i) {
        result += futures[i].get();
    }

    auto end = chrono::high_resolution_clock::now();
    auto spanMs = chrono::duration_cast<chrono::milliseconds>(end - start);
    cout << "==== Results for: " << name << " ====" << endl;
    cout << "Calculated result = " << result << endl;
    cout << "Total time = " << spanMs.count() << "ms" << endl;
    cout << "==== =========================== ====" << endl << endl;

}

int main() {
    cout << "Hardware concurrency = " << thread::hardware_concurrency() << endl << endl;

    // First test
    runThreads(getTen, "GET TEN");

    // Second test
    runThreads(getTenAndPrintThreadId, "GET TEN AND PRINT THREAD ID");

    cin.get();
}

Он запускает два теста. В каждом тесте он порождает 32 задачи через async. Каждое задание возвращает int. Результаты таких задач затем суммируются.

В первом тесте каждое задание просто возвращает 10 после 1 секунды задержки. Во втором тестовом задании те же самые, они просто выводят идентификатор потока в cout.

А вот выходные данные программы, работающей на моем 8-ядерном компьютере Win10, скомпилированном с MSVC.

Hardware concurrency = 8

==== Results for: GET TEN ====
Calculated result = 320
Total time = 3154ms
==== =========================== ====

10060
16920
520
356
11656
7504
14696
9344
4896
13196
11120
4792
7640
12764
6972
13244
4584
5420
14024
3744
8748
15440
12976
10060
16920
520
14820
356
7504
11656
4888
14696
==== Results for: GET TEN AND PRINT THREAD ID ====
Calculated result = 320
Total time = 2030ms
==== =========================== ====

Меня удивляет, что второй тест выполняется быстрее, чем первый, несмотря на то, что приходится выполнять больше работы. Если я поменяю numTasks на еще большее число, очевидно, что второй тест, как правило, быстрее. Это почему? Есть ли что-то, что я неправильно понял?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...