为了测试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();
}
它运行两个测试。在每个测试中,它通过async
产生32个任务。每个任务都返回一个int
。然后将这些任务的结果相加。
在第一个测试中,每个任务在延迟1秒后仅返回10。在第二个测试任务中,它们是相同的,它们也只将 thread-id 打印到cout
。
这是程序的输出,该程序在用MSVC编译的8核Win10机器上运行。
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
更改为更大的数字,很明显第二个测试通常会更快。这是为什么?我有误会吗?