我第一次在 MAC 上使用 C++ 中的线程。
下面是我的代码。 (我的代码背后的动机)
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
using namespace chrono;
const long long maxLimit = 2e9;
void getEvenSum(long long &sum) {
for(int i = 0 ; i <= maxLimit ; i+=2) {
sum += i;
}
}
void getOddSum(long long &sum) {
for(int i = 1 ; i <= maxLimit ; i+=2) {
sum += i;
}
}
int main() {
auto startTime = high_resolution_clock::now();
long long evenSum = 0 , oddSum = 0;
thread evenSumThread(getEvenSum, ref(evenSum));
thread oddSumThread(getOddSum, ref(oddSum));
evenSumThread.join();
oddSumThread.join();
auto endTime = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(endTime - startTime);
cout << " final sum is " << evenSum << " " << oddSum << endl;
cout << " time taken with thread :" << duration.count() / (long double)1e6 << endl;
startTime = high_resolution_clock::now();
evenSum = 0 , oddSum = 0;
getEvenSum(evenSum);
getOddSum(oddSum);
endTime = high_resolution_clock::now();
duration = duration_cast<microseconds>(endTime - startTime);
cout << " final sum is " << evenSum << " " << oddSum << endl;
cout << " time taken without thread " << duration.count() / (long double)1e6 << endl;
return 0;
}
输出:
final sum is 1000000001000000000 1000000000000000000
time taken with thread :5.01665
final sum is 1000000001000000000 1000000000000000000
time taken without thread 2.83442
输出结果非常出乎意料。线程化需要 5 秒,非线程化需要 2.8 秒。怎么办!!!
我尝试过但失败的解决方案,
g++ --std=c++11 file.cpp
g++ --std=c++11 -O3 -s -DNDEBUG file.cpp
(时间疯狂变化,但线程仍然需要更多时间)g++ --std=c++17 file.cpp
g++ clang++ -std=c++11 file.cpp
(出现错误,“CLANG”不存在)PS:当我上次在 Linux 中练习时(2 年前),相同的代码可以工作
在最新的 gcc 和 clang 上,
-O3
两个函数都已完全优化,您可以通过将其参数声明为 volatile
来防止这种情况。
void getEvenSum(volatile unsigned long long& sum) {
for (unsigned long long i = 0; i <= maxLimit; i += 2) {
sum += i;
}
}
这还将
int
转换为 unsigned long long
以避免有符号溢出,这是未定义的行为。
第二个问题现在是错误共享,解决这个问题的一种方法是将两个变量相互远离,或者将这些变量与缓存行边界对齐
alignas(64) unsigned long long evenSum = 0;
alignas(64) unsigned long long oddSum = 0;
这样您应该获得更快的线程版本代码。