c++ - 有两个线程的运行时间与一个线程的运行时间没有改善

标签 c++ multithreading performance

我是C++中多线程编程的新手。我写了一段简单的代码,将其粘贴在下面。
在两个线程中运行时,代码的完成速度仅比在单线程中运行时快。我遇到了其他类似的问题,但是它们是不同的,因为我没有共享资源,两个线程都需要访问这些资源来访问:

代码如下:

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

using namespace std;

typedef unsigned long long ull;

ull oddSum = 0;
ull evenSum = 0;

void addOdd(){
    for(int i = 1; i <= 1999999999; i++){
        if(i % 2 == 1)
            oddSum += i;
    }
}

void addEven(){
    for(int i = 1; i <= 1999999999; i++){
        if(i % 2 == 0)
            evenSum += i;
    }
}

int main(){
    auto startTime = std::chrono::high_resolution_clock::now();

    //Two threads
    std::thread t1(addEven);    //launch the two threads to run
    std::thread t2(addOdd); 

    t1.join();
    t2.join();    //wait for both to finish

    //One thread
    //addEven();
    //addOdd();

    auto stopTime = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(stopTime - startTime);

    cout << "Odd Sum: " << oddSum << endl;
    cout << "Even Sum: " << evenSum << endl;

    cout << elapsed.count()/(double)1000000 << endl;

    return 0;
}

当我使用单线程运行时,平均10次运行大约是 7.3秒

当我使用两个线程运行时,平均10次运行大约是 6.8秒

由于绝大多数时间都由函数中的循环占用,因此我相信并行运行两个线程(每个线程具有一个函数)将使运行时间减半。

注1 :我知道时间可能无法适本地减半,更有根据的猜测是两个线程的运行时间最长为5秒。我了解创建线程对象有其自身的开销。

注2 :也许我遗漏了一些东西,但是线程无法访问两者之间的任何共享位置。

任何想法都欢迎。我熟悉并发编程背后的理论,现在我才刚刚开始获得一些动手经验。我有一个4核的Intel i7。

最佳答案

当经常从不同线程访问变量时,应确保它们位于不同的缓存行(x86上为64字节宽)。

您可以通过对齐变量来做到这一点:

ull oddSum __attribute__((aligned(64))) = 0;
ull evenSum  __attribute__((aligned(64))) = 0;

未能这样做会有效地序列化写入操作,因为一次只能由一个CPU修改高速缓存行。

在多线程情况下,对齐变量会使我的运行时间减少30%。

正如@walnut在他的评论中提到的,如果您的编译器支持C++ 17,则可以通过可移植的方式来完成:
#include <new>
alignas(std::hardware_destructive_interference_size) ull oddSum = 0;
alignas(std::hardware_destructive_interference_size) ull evenSum  = 0;

关于c++ - 有两个线程的运行时间与一个线程的运行时间没有改善,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61219173/

相关文章:

c++ - 将 unsigned short/int 转换为 char *

c++ - C++中迭代器的指针如何在循环中变化?

c++ - extern const 链接规范似乎被 G++ 忽略

java - ThreadPoolExecutor, future : correlating requests and responses

javascript - 如何从随机数组对象创建关联数组?

java - 为什么我的多线程效率不高?

c++ - qProcess写关闭写 channel 后

GUI 中的 C# 多线程方法

multithreading - 具有OpenCL的GPU线程同步多核CPU线程

ios - 缓慢的 Swift 字符串性能