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

AMD 5600硬件随机数发生器(rdrand)在C++代码中速度不稳定原因排查

关于AMD 5600上RDRAND速度大幅波动的问题分析

在C++环境测试AMD 5600的硬件随机数发生器(RDRAND)时,发现其运行速度存在明显波动,想知道这种情况是否正常,或是代码实现存在问题?

测试代码

#include <iostream>
#include <chrono>
#include <cstdint>

int main()
{
    uint64_t random_num;
    int iter = 5'000'000;

    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < iter; i++) {
        __asm__ volatile("rdrand %0" : "=r"(random_num));
    }

    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

    std::cout << iter << " iterations in " << duration << " ms" << std::endl;

    return 0;
}

测试运行结果

mika@pc3 ~/t $ g++ -O2 rdrand.cpp -o rdrand
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 79 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 79 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 79 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 4458 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 4251 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 4312 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 4209 ms
mika@pc3 ~/t $ ./rdrand
5000000 iterations in 4571 ms

问题分析与解答

这种速度波动是正常现象,和你的代码实现无关,核心原因在于AMD Zen3架构(5600属于该架构)的RDRAND硬件实现机制:

  • RDRAND依赖CPU内置的硬件随机数生成器(HRNG)的熵池提供随机源。当熵池内的熵充足时,RDRAND可以快速返回随机数,对应你看到的79ms快速运行场景。
  • 当短时间内大量调用RDRAND,熵池被耗尽后,CPU会进入等待状态,直到HRNG重新积累足够的熵才能继续生成随机数,这就导致了运行时间大幅拉长(4000+ms的慢运行场景)。Zen3架构的HRNG熵补充速度相对有限,容易出现这种熵池耗尽的情况。

优化建议

  1. 避免高频直接调用RDRAND:如果需要大量随机数,建议用RDRAND初始化一个软件随机数生成器(比如XorShift、Mersenne Twister),后续通过软件生成器获取随机数,既能保证随机性,又能大幅提升性能。
  2. 添加返回值检查:RDRAND会通过CF标志位返回生成是否成功(虽然现代CPU失败概率极低),添加检查可以让代码更健壮。修改后的示例代码如下:
#include <iostream>
#include <chrono>
#include <cstdint>

int main()
{
    uint64_t random_num;
    int iter = 5'000'000;
    bool success;

    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < iter; i++) {
        __asm__ volatile("rdrand %0; setc %1" : "=r"(random_num), "=qm"(success));
        if (!success) {
            std::cerr << "RDRAND生成随机数失败!" << std::endl;
            return 1;
        }
    }

    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

    std::cout << iter << " iterations in " << duration << " ms" << std::endl;

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:29:55