在编写低级代码时是否有正确的方法来衡量性能?

时间:2013-05-22 18:11:00

标签: c x86-64 performance-testing

我正在为低级C / x64代码编写速度优化,我想知道是否有任何标准方法可以更快地可靠地测量哪个选项。

我比较技术A和B时的当前技术涉及重复A几百次,而不是重复B相同的时间,并比较每次的平均时间。然后我在几十个例子中重复这个,然后比较每种技术的 mean 均值。 (我的平均分钟也一样)

不幸的是,这种方法似乎存在一些问题。例如,如果我考虑使用第三种技术进行测试,但事实上使用B,那么B的第二次运行将几乎系统地更快(缓存效果?),更快地击败A。

还有更合适的技术来分析JIT编码吗?

2 个答案:

答案 0 :(得分:1)

这个功能应该可以解决问题。

static unsigned long long rdtsctime() {
    unsigned int eax, edx;
    unsigned long long val;
    __asm__ __volatile__("rdtsc":"=a"(eax), "=d"(edx));
    val = edx;
    val = val << 32;
    val += eax;
    return val;
}

调用一次获取当前时间,然后再次减去第一个值以获取经过时间(以周期为单位)。

答案 1 :(得分:0)

这是一个很好的问题。我一直在想自己衡量绩效的最佳方法是什么。我认为你不会找到一个简单的答案。我通常做的是创建一个函数指针,指向函数的不同变体,然后在几次迭代中计算每个函数的时间。我使用OpenMP中的函数(即使不使用任何线程)omp_get_wtime()来执行计时。例如,让我们假设 我有一个函数的两个变体,foo_v1foo_v2,它使数组a包含多个元素n。我可能用来衡量这两个函数性能的通用方法如下:

#include <stdio.h>
#include <omp.h>
void foo_v1(float *a, const int n) {
   //    
}
void foo_v2(float *a, const int n) {
   //    
}
int main() {
    const int n = 1000;
    float *a = new float[n];
    void (*fp[2])(float *a, const int n);
    fp[0] = foo_v1;
    fp[1] = foo_v2;
    const int nrepeat = 1000; //some number large so that the functions take at least a second to finish
    for(int j=0; j<2; j++) {
        double dtime = omp_get_wtime();
        for(int i=0; i<nrepeat; i++) {    
            fp[j](a, n);
        }
        dtime = omp_get_wtime() - dtime;
        printf("time in seconds %f\n", dtime);
     }
     delete[] a;
}

你可以在这里看到一个例子,说明我在这里做了16个函数变体。 Speedup a short to float cast?

我不确定这种比较性能的方法有多好,但它是我一直在使用的方法。