在这种情况下,为什么函数调用比扁平函数更快?

时间:2017-11-15 03:06:45

标签: c openmp

我现在正在进行代码优化。 所以我认为函数调用部分是开销,所以我删除了函数调用并取出了它内部的代码。然后我认为开销已经消失,所以它应该运行得更快,但运行速度较慢。你知道为什么吗?

这是我的代码。

主要文件

for(i = 0; i < l.batch; ++i){       
    im2col_cpu(state.input, l.c, l.h, l.w, l.size, l.stride, l.pad, b);     
    gemm(0,0,m,n,k,1,a,k,b,n,1,c,n);
}

gemm功能

void gemm(int TA, int TB, int M, int N, int K, float ALPHA, 
    float *A, int lda, 
    float *B, int ldb,
    float BETA,
    float *C, int ldc)  
{  
  gemm_cpu( TA,  TB,  M, N, K, ALPHA,A,lda, B, ldb,BETA,C,ldc);  
}

gemm_cpu功能

void gemm_cpu(int TA, int TB, int M, int N, int K, float ALPHA, 
    float *A, int lda, 
    float *B, int ldb,
    float BETA,
    float *C, int ldc)
{ 
    int i, j;
    for(i = 0; i < M; ++i){
      for(j = 0; j < N; ++j){
        C[i*ldc + j] *= BETA;
      }
    }

    int t;
#pragma omp parallel for
    for (t = 0; t < M; ++t) {
        if (!TA && !TB)
            gemm_nn(1, N, K, ALPHA, A + t*lda, lda, B, ldb, C + t*ldc, ldc);
        else if (TA && !TB)
            gemm_tn(1, N, K, ALPHA, A + t, lda, B, ldb, C + t*ldc, ldc);
        else if (!TA && TB)
            gemm_nt(1, N, K, ALPHA, A + t*lda, lda, B, ldb, C + t*ldc, ldc);
        else
            gemm_tt(1, N, K, ALPHA, A + t, lda, B, ldb, C + t*ldc, ldc);
    }
}

gemm_nn

void gemm_nn(int M, int N, int K, float ALPHA, 
    float *A, int lda, 
    float *B, int ldb,
    float *C, int ldc)      
{
  int i,j,k;
  for(i = 0; i < M; ++i){ 
    for(k = 0; k < K; ++k){
        register float A_PART = ALPHA*A[i*lda+k];   

        for(j = 0; j < N; ++j){
            C[i*ldc+j] += A_PART*B[k*ldb+j];    
        }
    }
  }
}

这些是原始代码。但我只需要gemm_nn功能。所以,我把代码拉出到Main文件中。这是改变了代码。

主要文件(已更改)

for(i = 0; i < l.batch; ++i){       
    im2col_cpu(state.input, l.c, l.h, l.w, l.size, l.stride, l.pad, b);     
    //gemm(0,0,m,n,k,1,a,k,b,n,1,c,n);  

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            c[i*n + j] *= 1;
        }
    }

    int i;
    #pragma omp parallel for
    for(i = 0; i < m; ++i) {
        int j, v;
        for( j = 0; j < k; ++j) {
            register float A_PART = 1 * a[i * k + j];
            for(v = 0; v < n; ++v) {
                c[i * n + v] += A_PART * b[j * n + v];
            }
        }
    }
}

但结果与我的预期不同。

Function call style is much faster than flattening(the code that i changed)

我不知道为什么函数调用样式比没有函数调用样式更快。<​​/ p>

0 个答案:

没有答案