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

C++中如何以时钟周期为单位测量指令执行时间及相关验证

关于时钟周期计算函数与指令执行时间测量的问题

核心疑问

  • 不确定自己实现的calcClockCycles函数是否正确
  • 不清楚以时钟周期为单位测量指令执行时间的精确公式
  • 测试发现v1 = v2;的测量结果为1时钟单位,但该语句对应2条movaps指令,对结果准确性存疑
  • 当前处于Debug无优化编译模式,开发编程语言过程中需要估算表达式的时钟周期,但难以构建合理的估算方式

背景说明

需要测量_multiply等多个函数的执行时间,且要求测量结果固定不变。已将原函数名calcClock修改为calcClockCycles,变量totalPerformedInstructions改为totalPerformedExpressions。使用的CPU为Intel(R) Core(TM) i7-5500U @2.40GHz,代码中GHz参数设为2.4。

代码实现

Chrono结构体代码

#include <chrono>
struct Chrono {
    // Referenced from:
    // - https://en.cppreference.com/w/cpp/chrono/high_resolution_clock/now
    // - https://levelup.gitconnected.com/8-ways-to-measure-execution-time-in-c-c-48634458d0f9

private:
    std::chrono::high_resolution_clock::time_point _start, _end;

public:
    void start() {
        _start = std::chrono::high_resolution_clock::now();
    }
    void end() {
        _end = std::chrono::high_resolution_clock::now();
    }
    double elapsed() {
        std::chrono::duration<double> diff = _end - _start;
    }
    double calcClockCycles(int totalPerformedExpressions, float GHz) { // I set GHz to 2.4 with "Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz (4 CPUs), ~2.4GHz".
        return elapsed() / totalPerformedExpressions * GHz*1000*1000*1000;
    }
};

main.cpp应用示例

Chrono g_ch;
int g_iterations = 2*1000*1000;
float g_GHz = 2.4f;

#define ITERx100_EXPRESSIONS(X) \
    for (int i = 0; i < g_iterations; i++) { \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
        X; X; X; X; X; X; X; X; X; X; \
    }

inline vec2 _multiply(const vec2 &_v, const mat2x2 &_M) {
    // |6|T   |2 3|T   |6*2+4*3|   |24|
    // |4|  * |7 5|  = |6*7+4*5| = |62|
    
    #if defined(__GNUC__)
        // M = {[0],[1],
        //      [2],[3]}
        v4sf o;
        v4sf &v = *(v4sf *)&_v;
        v4sf &M = *(v4sf *)&_M;
        #if 0
            o[0] = v[0]*M[0] + v[1]*M[1];
            o[1] = v[0]*M[2] + v[1]*M[3];
        #elif 1
            // v4sf a = __builtin_shuffle(v, v4si{0,1,0,1}) * M;
            // o[0] = a[0] + a[1];
            // o[1] = a[2] + a[3];
            //
            // v4sf a = __builtin_shuffle(v, v4si{0,1,0,1}) * M;
            // o = __builtin_shuffle(a, v4si{0,2}) + __builtin_shuffle(a, v4si{1,3});
            
            v4sf a = __builtin_shuffle(v, v4si{0,0,1,1}) * __builtin_shuffle(M, v4si{0,2,1,3});
            o = a + __builtin_shuffle(a, v4si{2,3});
        #endif
        return *(vec2 *)&o;
    #else
        return _multiply_slow(_v, _M);
    #endif
}

void mat2x2_vxM() {
    mat2x2 M = v4sf{
        2,3,
        7,5,
    };
    vec2 v(6,4);
    vec2 V;

    g_ch.start();
    ITERx100_EXPRESSIONS(V = _multiply(v, M));
    g_ch.end();
    printf("%s: %s, %g\n", __func__, to_string(V).c_str(), g_ch.calcClockCycles(100 * g_iterations, g_GHz));
}

int main() {
    mat2x2_vxM();
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:45:53