矩阵乘的性能问题
矩阵乘实现的性能问题.
下面代码示例的两个矩阵乘实现, 一个是gemm_nt, 行列乘; 一个是gemm_nn, 行行乘. 计算量看上去是一样的,
但实测性能一个天上一个地下, 有近7倍+的差距.
在我的电脑上, release模式下, 一个是4.89s, 一个是32.35ms.
我看了一下汇编, 两者也接近, 那为什么会有如此之大的性能差别呢?
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
float *random_matrix(int rows, int cols)
{
int i;
float *k = (float *)calloc(rows*cols, sizeof(float));
for(i = 0; i < rows*cols; ++i){
k[i] = (float)rand()/RAND_MAX;
}
return k;
}
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];
}
}
}
}
void gemm_nt(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(j = 0; j < N; ++j){
register float sum = 0;
for(k = 0; k < K; ++k){
sum += ALPHA*A[i*lda+k]*B[j*ldb + k];
}
C[i*ldc+j] += sum;
}
}
}
#define _DIM 1000
#define _NUM 10
int _tmain(int argc, _TCHAR* argv[])
{
float *a = random_matrix(_DIM,_DIM);
int lda = _DIM;
float *b = random_matrix(_DIM,_DIM);
int ldb = _DIM;
float *c = random_matrix(_DIM,_DIM);
int i;
clock_t start;
start = clock();
for(i = 0; i<_NUM; ++i){
gemm_nn(_DIM,_DIM,_DIM,1,a,lda,b,ldb,c,_DIM);
}
printf("gemm_nn = %lf s\n",(float)(clock()-start)/CLOCKS_PER_SEC);
start = clock();
for(i = 0; i<_NUM; ++i){
gemm_nt(_DIM,_DIM,_DIM,1,a,lda,b,ldb,c,_DIM);
}
printf("gemm_nt = %lf s\n",(float)(clock()-start)/CLOCKS_PER_SEC);
free(a);
free(b);
free(c);
return 0;
}