Если вы не используете встроенные функции SSE2 или не используете тип данных, который может не повысить производительность с ними, вы можете попытаться транспонировать матрицу для легкого улучшения производительности для больших умножений матриц с cblas_?dot
.Выполнение умножения матриц в блоках также помогает.
void matMulDotProduct(int n, float *A, float* B, int a_size, int b_size, int a_row, int a_col, int b_row, int b_col, float *C) {
int i, j, k;
MKL_INT incx, incy;
incx = 1;
incy = b_size;
//copy out multiplying matrix from larger matrix
float *temp = (float*) malloc(n * n * sizeof(float));
for (i = 0; i < n; ++i) {
cblas_scopy(n, &B[(b_row * b_size) + b_col + i], incy, &temp[i * n], 1);
}
//transpose
mkl_simatcopy('R', 'T', n, n, 1.0, temp, 1, 1);
for (i = 0; i < n; i+= BLOCK_SIZE) {
for (j = 0; j < n; j++) {
for (k = 0; k < BLOCK_SIZE; ++k) {
C[((i + k) * n) + j] = cblas_sdot(n, &A[(a_row + i + k) * a_size + a_col], incx, &temp[n * j], 1);
}
}
}
free(temp);
}
На моей машине этот код примерно на 1 порядок быстрее, чем код с 3 циклами (но также на 1 порядок медленнее, чем вызов cblas_? Gemm) для операций с плавающей запятой одинарной точности и 2K на 2Kматрицы.(Я использую Intel MKL).