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

C++混用deferred与async和仅用async耗时无差异问题排查

问题根因
  • 存在多余同步计算:循环内第一行objects[i].generateNumbers()已经同步执行了一遍随机数生成逻辑,这部分耗时占总耗时的绝大部分,完全掩盖了后续异步逻辑的性能差异,同时属于无意义的重复计算。
  • 未实现真正的并行执行:创建std::future后立刻调用get()会阻塞主线程,直到当前任务执行完成再进入下一轮循环,无论使用哪种启动策略,所有任务都是串行执行,自然不会有性能差异。
  • 附加问题:rand()为线程不安全函数,多线程并发调用会产生数据竞争,也会干扰性能测试结果,建议替换为C++11 <random>库提供的线程安全随机数生成器。
修正后的代码
#include <iostream>
#include <chrono>
#include <future>
#include <vector>

using namespace std;

class RandomNumberGenerator
{
public:
     enum class task { LIGHT, HEAVY };
     task taskType;

    RandomNumberGenerator(): taskType(task::LIGHT)
    {
        int rnd = rand() % 2;
        taskType = (rnd == 0) ? task::LIGHT : task::HEAVY;
    }

    bool generateNumbers()
    {
        int number;
        if(taskType == task::LIGHT)
        {
            for (int i = 0; i < 100; i++)
            {
                number = rand();
            }
        }
        else
        {
            for (int i = 0; i < 1000000; i++)
            {
                number = rand();
            }
        }
        return true;
    }
};

int main()
{    
    cout << "Starting to generate numbers\n";
    RandomNumberGenerator objects[100];
    vector<future<bool>> futures;
    futures.reserve(100);

    auto start = chrono::system_clock::now();

    // 先启动所有异步任务,不阻塞
    for (int i = 0; i < 100; i++) 
    {
        if (objects[i].taskType == RandomNumberGenerator::task::LIGHT)
        {
            futures.push_back(async(launch::deferred, &RandomNumberGenerator::generateNumbers, &objects[i]));
        }
        else
        {
            futures.push_back(async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]));
        }

        // 全async方案替换为下面一行
        // futures.push_back(async(launch::async, &RandomNumberGenerator::generateNumbers, &objects[i]));
    }

    // 所有任务启动完成后再逐个获取结果
    for (auto& fut : futures) {
        bool result = fut.get();
    }

    auto end = chrono::system_clock::now();
    cout << "Total time = " << chrono::duration_cast<chrono::milliseconds>(end - start).count() << " 毫秒\n";
    return 0;
}

修正后即可观测到两种启动策略的性能差异:混用deferred的方案因为轻量任务避免了线程创建、调度的额外开销,耗时会明显低于全async方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:54:04