由于C函数调用导致的开销很大

时间:2015-01-19 07:52:23

标签: c performance inline

我有一个简单的函数,它将两个矩阵相乘。

void mmul1(float A[ni][nk], float B[nk][nj], float C[ni][nj])
{
    int i, j, k;
    for (i=0; i<ni; i++) {
        for (j=0; j<nj; j++) {
            C[i][j] = 0;
            for (k=0; k<nk; k++) {
                C[i][j] += A[i][k]*B[k][j];
            }
        }
    }
}

我有一个主要功能,如下所示:

int main(int argc, char** argv) {

    // timer structs
    struct  timeval ts, te, td;
    float tser, tpar, diff;
    int i, j, k;

    printf("matrix size : %d x %d x %d\n", ni, nj, nk);

    srand(0);

    // initialization
    for (i=0; i<ni; i++) {
        for (k=0; k<nk; k++) {
            A[i][k] = (float)rand()/RAND_MAX;
        }
    }
    for (k=0; k<nk; k++) {
        for (j=0; j<nj; j++) {
            B[k][j] = (float)rand()/RAND_MAX;
        }
    }

    gettimeofday(&ts, NULL);
    for (i=0; i<ni; i++) {
        for (j=0; j<nj; j++) {
            Cans[i][j] = 0;
            for (k=0; k<nk; k++) {
                Cans[i][j] += A[i][k]*B[k][j];
            }
        }
    }
    gettimeofday(&te, NULL);
    timersub(&ts, &te, &td);
    tser = fabs(td.tv_sec+(float)td.tv_usec/1000000.0);

    gettimeofday(&ts, NULL);
    mmul1(A, B, C);
    gettimeofday(&te, NULL);
    timersub(&ts, &te, &td);
    tpar = fabs(td.tv_sec+(float)td.tv_usec/1000000.0);

    // compare results
    diff = compute_diff(C, Cans);

    printf("Performance : %.2f GFlop/s (%.1fX)\n", 2.0*ni*nj*nk/tpar/1000000000, tser/tpar );
    printf("Result Diff : %.3f\n", diff );

    return 0;
}

我正在使用gcc&#39; -O3标志进行编译。

测试时,我发现如果我将static inline添加到mult的签名,那么在512x512矩阵上进行测试时,我会获得5倍的加速。与乘法相比,函数调用的开销应该可以忽略不计。为什么会出现性能损失(编译器生成不同的机器代码?),如何在没有inline mult的情况下修复它?

1 个答案:

答案 0 :(得分:1)

由于您未在main中使用结果,因此当您inline该功能时,优化程序可以看到没有正在使用的副作用,并且可以自由删除所有副作用矩阵乘法码。

您可以使用gcc的{​​{1}}标志来查看生成的汇编代码。