Why function call is faster than flattening function in this case?

Viewed 147

I'm doing code optimization right now. So I think the function call part is overhead, so I deleted the function call and pulled out the code inside it. Then I think the overhead is gone, so it should run faster, but it runs slower. Do you know why?

This is my code.

Main File

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 Function

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 Function

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];    
        }
    }
  }
}

These are original code. But I need only gemm_nn function. So, I pulled out the code to Main file. This is changed code.

Main File(Changed)

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];
            }
        }
    }
}

But result is different that what I expected.

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

I don't know why the function call style is faster than no function call style.

0 Answers
Related