cBlas 性能 + 速度

cBlas performance + speed

本文关键字:速度 性能 cBlas      更新时间:2023-10-16

我使用cBLAS并进行了一些速度测试,我对结果感到惊讶:

#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
#include  <GL/glfw.h>
    void matriz_matriz(float *matriz1,float *matriz2,float *matrizr){
      matrizr[0]  = (matriz1[0]*matriz2[0])+(matriz1[4]*matriz2[1])  +(matriz1[8]*matriz2[2])  +(matriz1[12]*matriz2[3]);
      matrizr[1]  = (matriz1[1]*matriz2[0])+(matriz1[5]*matriz2[1])  +(matriz1[9]*matriz2[2])  +(matriz1[13]*matriz2[3]);
      matrizr[2]  = (matriz1[2]*matriz2[0])+(matriz1[6]*matriz2[1])  +(matriz1[10]*matriz2[2]) +(matriz1[14]*matriz2[3]);
      matrizr[3]  = (matriz1[3]*matriz2[0])+(matriz1[7]*matriz2[1])  +(matriz1[11]*matriz2[2]) +(matriz1[15]*matriz2[3]);
      matrizr[4]  = (matriz1[0]*matriz2[4])+(matriz1[4]*matriz2[5])  +(matriz1[8]*matriz2[6])  +(matriz1[12]*matriz2[7]);
      matrizr[5]  = (matriz1[1]*matriz2[4])+(matriz1[5]*matriz2[5])  +(matriz1[9]*matriz2[6])  +(matriz1[13]*matriz2[7]);
      matrizr[6]  = (matriz1[2]*matriz2[4])+(matriz1[6]*matriz2[5])  +(matriz1[10]*matriz2[6]) +(matriz1[14]*matriz2[7]);
      matrizr[7]  = (matriz1[3]*matriz2[4])+(matriz1[7]*matriz2[5])  +(matriz1[11]*matriz2[6]) +(matriz1[15]*matriz2[7]);
      matrizr[8]  = (matriz1[0]*matriz2[8])+(matriz1[4]*matriz2[9])  +(matriz1[8]*matriz2[10]) +(matriz1[12]*matriz2[11]);
      matrizr[9]  = (matriz1[1]*matriz2[8])+(matriz1[5]*matriz2[9])  +(matriz1[9]*matriz2[10]) +(matriz1[13]*matriz2[11]);
      matrizr[10] = (matriz1[2]*matriz2[8])+(matriz1[6]*matriz2[9])  +(matriz1[10]*matriz2[10])+(matriz1[14]*matriz2[11]);
      matrizr[11] = (matriz1[3]*matriz2[8])+(matriz1[7]*matriz2[9])  +(matriz1[11]*matriz2[10])+(matriz1[15]*matriz2[11]);
      matrizr[12] = (matriz1[0]*matriz2[12])+(matriz1[4]*matriz2[13])+(matriz1[8]*matriz2[14]) +(matriz1[12]*matriz2[15]);
      matrizr[13] = (matriz1[1]*matriz2[12])+(matriz1[5]*matriz2[13])+(matriz1[9]*matriz2[14]) +(matriz1[13]*matriz2[15]);
      matrizr[14] = (matriz1[2]*matriz2[12])+(matriz1[6]*matriz2[13])+(matriz1[10]*matriz2[14])+(matriz1[14]*matriz2[15]);
      matrizr[15] = (matriz1[3]*matriz2[12])+(matriz1[7]*matriz2[13])+(matriz1[11]*matriz2[14])+(matriz1[15]*matriz2[15]);
    }

    int main(){
      int i;
      double tiempo1;
      double tiempo2;
      glfwInit();
      float *mat0 = NULL;
      float *mat1 = NULL;
      float *mat2 = NULL;
      mat0  = (float *)malloc(16 * sizeof(float));
      mat1  = (float *)malloc(16 * sizeof(float));
      mat2  = (float *)malloc(16 * sizeof(float));
      mat0[0]  =  1.0;
      mat0[1]  =  0.0;
      mat0[2]  =  0.0;
      mat0[3]  =  0.0;
      mat0[4]  =  0.0;
      mat0[5]  =  1.0;
      mat0[6]  =  0.0;
      mat0[7]  =  0.0;
      mat0[8]  =  0.0;
      mat0[9]  =  0.0;
      mat0[10] =  1.0;
      mat0[11] =  0.0;
      mat0[12] =  3.281897;
      mat0[13] =  4.714289;
      mat0[14] =  5.124306;
      mat0[15] =  1.0;
      mat1[0]  =  1.0;
      mat1[1]  =  0.0;
      mat1[2]  =  0.0;
      mat1[3]  =  0.0;
      mat1[4]  =  0.0;
      mat1[5]  =  0.924752;
      mat1[6]  =  0.380570;
      mat1[7]  =  0.0;
      mat1[8]  =  0.0;
      mat1[9]  = -0.380570;
      mat1[10] =  0.924752;
      mat1[11] =  0.0;
      mat1[12] =  0.0;
      mat1[13] =  0.0;
      mat1[14] =  0.0;
      mat1[15] =  1.0;
      mat2[0]  =  1.0;
      mat2[1]  =  0.0;
      mat2[2]  =  0.0;
      mat2[3]  =  0.0;
      mat2[4]  =  0.0;
      mat2[5]  =  1.0;
      mat2[6]  =  0.0;
      mat2[7]  =  0.0;
      mat2[8]  =  0.0;
      mat2[9]  =  0.0;
      mat2[10] =  1.0;
      mat2[11] =  0.0;
      mat2[12] =  0.0;
      mat2[13] =  0.0;
      mat2[14] =  0.0;
      mat2[15] =  1.0;
       tiempo1 = glfwGetTime();
       for(i=0;i<100000;i++){
        matriz_matriz(mat0,mat1,mat2);
        //cblas_sgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,4,4,4,1.0f,mat0,4,mat1,4,0.0f,mat2,4);
       }
      tiempo2 = glfwGetTime();
      printf("Tiempo total: %fn",tiempo2-tiempo1);
      for(i=0;i<16;i++)printf("valor[%i]: %fn",i,mat2[i]);
      free(mat0);
      free(mat1);
      free(mat2);
      system("pause");
      glfwTerminate();
      return 0;
    }

如果我使用函数 cblas_sgemm (...) tiempo2 - tiempo1 返回 0.096924 的值,但如果我使用自己的函数 ( matriz_matriz(...) ) tiempo2 - tiempo1 返回 0.046271 的值

会发生什么?我的函数比Cblas快。

此测试在装有奔腾 3 处理器的 PC 上进行了测试。谁能告诉我发生了什么?

谢谢。

您的计时结果有效。您的matriz_matriz函数使用完全展开进行矩阵-矩阵乘法。这是一种标准的优化技术。请参阅 http://en.wikipedia.org/wiki/Loop_unwinding。

问题是您的函数仅适用于 4X4 矩阵。如果您尝试创建通用乘法函数,则必须使用for循环。然后执行时间将增加。

有关优化的 BLAS 例程,请参阅 ATLAS 和 OpenBLAS 库。

  • http://math-atlas.sourceforge.net/
  • http://www.openblas.net/