c - 如何测量一小段 C/汇编代码的速度?

标签 c linux performance assembly

考虑这个 C 代码:

#include <complex.h>
complex float f(complex float x[]) {
  complex float p = 1.0;
  for (int i = 0; i < 32; i++)
    p += x[i];
  return p;
}

使用 -O3 -march=core-avx2 运行的英特尔 C 编译器给出:

f:
        vmovups   ymm1, YMMWORD PTR [rdi]                       #5.10
        vmovups   ymm2, YMMWORD PTR [64+rdi]                    #5.10
        vmovups   ymm5, YMMWORD PTR [128+rdi]                   #5.10
        vmovups   ymm6, YMMWORD PTR [192+rdi]                   #5.10
        vmovsd    xmm0, QWORD PTR p.152.0.0.1[rip]              #3.19
        vaddps    ymm3, ymm1, YMMWORD PTR [32+rdi]              #3.19
        vaddps    ymm4, ymm2, YMMWORD PTR [96+rdi]              #3.19
        vaddps    ymm7, ymm5, YMMWORD PTR [160+rdi]             #3.19
        vaddps    ymm8, ymm6, YMMWORD PTR [224+rdi]             #3.19
        vaddps    ymm9, ymm3, ymm4                              #3.19
        vaddps    ymm10, ymm7, ymm8                             #3.19
        vaddps    ymm11, ymm9, ymm10                            #3.19
        vextractf128 xmm12, ymm11, 1                            #3.19
        vaddps    xmm13, xmm11, xmm12                           #3.19
        vmovhlps  xmm14, xmm13, xmm13                           #3.19
        vaddps    xmm15, xmm13, xmm14                           #3.19
        vaddps    xmm0, xmm15, xmm0                             #3.19
        vzeroupper                                              #6.10
        ret                                                     #6.10

带有 -O3 -march=core-avx2 -ffast-math 的 gcc 版本 7(快照)给出:

f:
        lea     r10, [rsp+8]
        and     rsp, -32
        push    QWORD PTR [r10-8]
        push    rbp
        mov     rbp, rsp
        push    r10
        vmovups ymm0, YMMWORD PTR [rdi+64]
        vmovaps ymm1, YMMWORD PTR .LC0[rip]
        vaddps  ymm0, ymm0, YMMWORD PTR [rdi+32]
        vaddps  ymm1, ymm1, YMMWORD PTR [rdi]
        vaddps  ymm0, ymm0, ymm1
        vmovups ymm1, YMMWORD PTR [rdi+128]
        vaddps  ymm1, ymm1, YMMWORD PTR [rdi+96]
        vaddps  ymm0, ymm0, ymm1
        vmovups ymm1, YMMWORD PTR [rdi+192]
        vaddps  ymm1, ymm1, YMMWORD PTR [rdi+160]
        vaddps  ymm0, ymm0, ymm1
        vaddps  ymm0, ymm0, YMMWORD PTR [rdi+224]
        vunpckhps       xmm3, xmm0, xmm0
        vshufps xmm2, xmm0, xmm0, 255
        vshufps xmm1, xmm0, xmm0, 85
        vaddss  xmm1, xmm2, xmm1
        vaddss  xmm3, xmm3, xmm0
        vextractf128    xmm0, ymm0, 0x1
        vunpckhps       xmm4, xmm0, xmm0
        vshufps xmm2, xmm0, xmm0, 85
        vaddss  xmm4, xmm4, xmm0
        vshufps xmm0, xmm0, xmm0, 255
        vaddss  xmm0, xmm2, xmm0
        vaddss  xmm3, xmm3, xmm4
        vaddss  xmm1, xmm1, xmm0
        vmovss  DWORD PTR [rbp-24], xmm3
        vmovss  DWORD PTR [rbp-20], xmm1
        vzeroupper
        vmovq   xmm0, QWORD PTR [rbp-24]
        pop     r10
        pop     rbp
        lea     rsp, [r10-8]
        ret 

我感兴趣的是哪个更快,所以测量运行时间会很棒。

但是,我不知道如何衡量花费这么少时间的代码的运行时间。

Which code is faster and how can one measure it reliably?

最佳答案

您需要一个可以多次调用此函数的测试工具。

这将使运行时达到一个非常重要的水平,并将平衡由操作系统调度引起的任何差异。

void test_f() 
{
    complex float x[32] = { 1+2i, 2+3i };    // add as many as needed. 
                                             // here i is a special
                                             // constant for complex numbers
    int i;
    for (i=0; i<10000000; i++) {
        f(x);
    }
}

关于c - 如何测量一小段 C/汇编代码的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41990083/

相关文章:

linux - Bash 脚本由于 pipping 调用子 shell

python - Google App Engine Python - Protorpc && 任务队列

c - 合并排序和反转算法

c - 什么是文件描述符的 "exception"?

linux - 在 *nix 上有没有办法在未来的日期和时间触发进程?

linux - 如何检查 Xorg 是否在 emacs lisp 中运行?

android - 如何在 Android 中正确实现 feed(类似于 Facebook/Instagram)?

c++ - 在c++中使用哪个字符串类可以实现高性能并且简单

C 程序跳过 switch 语句中的部分函数。

c - 仅针对无符号值处理字节顺序的函数