You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++向量求和场景下并行代码运行速度慢于串行代码问题咨询

性能劣化原因
  • 核心问题是锁粒度过细导致完全失去并行收益:你的代码里每累加一个向量元素就执行一次Mutex.lock()/Mutex.unlock(),1000万次的加解锁本身就有极高的开销,且互斥锁保证同一时间只有一个线程能修改全局Sum变量,相当于所有线程的计算过程实际是串行执行的,8线程场景下还额外增加了大量锁竞争、线程上下文切换的成本,因此耗时远高于单线程版本。
  • 额外固定开销:线程创建、调度本身也有固定成本,在你的实现里并行收益完全为负的情况下,这些成本会进一步拉高耗时。
优化方案

最优解法是取消全局累加的互斥锁,改为线程局部求和后统一合并,每个线程仅计算自己负责分片的和,存在局部变量中,所有线程执行完毕后主线程再把所有分片的和加总即可,全程无锁竞争,能充分利用多核性能。

优化后参考代码

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <cmath>

using namespace std;

/* 并行求和函数:返回当前分片的求和结果 */
double Function_Sum(const vector<double>& Vector, unsigned int kin, unsigned int kend)
{
    double local_sum = 0;
    for(unsigned int k = kin; k <= kend; ++k)
    {
        // 无锁,仅操作线程局部变量,无竞争
        local_sum += Vector[k];
    }
    return local_sum;
}

int main(int argc, char *argv[])
{
    unsigned int ThreadsSize = 8;
    vector<thread> Threads;
    // 存储每个线程的局部求和结果
    vector<double> thread_sums(ThreadsSize, 0);
    
    vector<double> Vector(10000000,1);
    
    unsigned int kin, kend;
    unsigned int dk = floor(Vector.size() / ThreadsSize);
    
    cout << "VectorSize = " << Vector.size() << ", ThreadsSize = " << ThreadsSize << ", dk = " << dk << endl;
    
    auto t_start = std::chrono::high_resolution_clock::now();
    for(unsigned int k = 0; k < ThreadsSize; ++k)
    {
        kin = k * dk;
        kend = (k + 1) * dk - 1;
        if(k == ThreadsSize - 1)
        {
            kend = Vector.size() - 1;
        }
        cout << k << " in: " << kin << ", end: " << kend << endl;
        // 把对应位置的引用传给线程,存局部求和结果
        Threads.emplace_back([&, k, kin, kend](){
            thread_sums[k] = Function_Sum(Vector, kin, kend);
        });
    }
    
    for(auto& t : Threads)
    {
        t.join();
    }
    
    // 合并所有线程的结果
    double Sum = 0;
    for(auto s : thread_sums) Sum += s;
    
    auto t_end = std::chrono::high_resolution_clock::now();
    double elapsed_time_ms = std::chrono::duration<double, std::milli>(t_end-t_start).count();
    
    cout << "Sum = " << Sum << endl;
    cout << "Time = " << elapsed_time_ms << endl;
    return 0;
}

优化后8线程耗时会接近单线程的1/8,符合预期。

内容的提问来源于stack exchange,提问作者FGP92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:27:00