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

为何添加C++20 likely/unlikely属性的代码运行速度未升反降?

性能异常问题排查
  • 运行环境:Visual Studio 2019 Version 16.11.8,开启/O2优化选项,测试硬件为Intel CPU
  • 异常现象:经t-test统计验证,未添加分支属性的代码运行速度在统计意义上快于添加了C++20 [[likely]]/[[unlikely]]属性的版本,该结果与分支提示属性的优化预期相悖
  • 排查难点:暂无法确定性能差异的诱因是缓存(cache)相关影响,还是编译器的特殊优化逻辑;因不具备汇编代码阅读能力,无法直接从汇编层面对问题进行排查

测试代码如下:

#include <chrono>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
#include <cmath>
#include <functional>

static const size_t NUM_EXPERIMENTS = 1000;

double calc_mean(std::vector<double>& vec) {
    double sum = 0;
    for (auto& x : vec)
        sum += x;
    return sum / vec.size();
}

double calc_deviation(std::vector<double>& vec) {
    double sum = 0;
    for (int i = 0; i < vec.size(); i++)
        sum = sum + (vec[i] - calc_mean(vec)) * (vec[i] - calc_mean(vec));
    return sqrt(sum / (vec.size()));
}

double calc_ttest(std::vector<double> vec1, std::vector<double> vec2){
    double mean1 = calc_mean(vec1);
    double mean2 = calc_mean(vec2);
    double sd1 = calc_deviation(vec1);
    double sd2 = calc_deviation(vec2);
    double t_test = (mean1 - mean2) / sqrt((sd1 * sd1) / vec1.size() + (sd2 * sd2) / vec2.size());
    return t_test;
}

namespace with_attributes {
    double calc(double x) noexcept {
        if (x > 2) [[unlikely]]
            return sqrt(x);
        else [[likely]]
            return pow(x, 2);
    }
}  // namespace with_attributes


namespace no_attributes {
    double calc(double x) noexcept {
        if (x > 2)
            return sqrt(x);
        else
            return pow(x, 2);
    }
}  // namespace with_attributes

std::vector<double> benchmark(std::function<double(double)> calc_func) {
    std::vector<double> vec;
    vec.reserve(NUM_EXPERIMENTS);

    std::mt19937 mersenne_engine(12);
    std::uniform_real_distribution<double> dist{ 1, 2.2 };

    for (size_t i = 0; i < NUM_EXPERIMENTS; i++) {

        const auto start = std::chrono::high_resolution_clock::now();
        for (auto size{ 1ULL }; size != 100000ULL; ++size) {
            double x = dist(mersenne_engine);
            calc_func(x);
        }
        const std::chrono::duration<double> diff =
            std::chrono::high_resolution_clock::now() - start;
        vec.push_back(diff.count());
    }
    return vec;
}

int main() {

    std::vector<double> vec1 = benchmark(with_attributes::calc);
    std::vector<double> vec2 = benchmark(no_attributes::calc);
    std::cout << "with attribute: " << std::fixed << std::setprecision(6) << calc_mean(vec1) << '\n';
    std::cout << "without attribute: " << std::fixed << std::setprecision(6) << calc_mean(vec2) << '\n';
    std::cout << "T statistics" << std::fixed << std::setprecision(6) << calc_ttest(vec1, vec2) << '\n';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:21:16