繁体   English   中英

使用 openmp 并行化矩阵乘法并使用 avx2 进行矢量化

[英]Matrix multiplication paralellize with openmp and vectorized with avx2

(1) 对于某些大小(矩阵大小)代码工作正常,但对于某些大小,它计算错误的矩阵乘法,虽然我仔细使用 Avx2 指令集但我无法弄清楚问题出在哪里。

(2) 当我仅使用 Avx2 指令集对代码进行向量化时,与使用 avx2 对代码进行向量化并使用 Openmp 并行化时相比,执行时间更少。 尽管使用矢量化(Avx2)和并行化(Openmp)时执行时间应该更短。

void mat_mul_pl(int size, double **mat1, double **mat2, double **result)
{
__m256d vec_multi_res = _mm256_setzero_pd(); //Initialize vector to zero
__m256d vec_mat1 = _mm256_setzero_pd(); //Initialize vector to zero
__m256d vec_mat2 = _mm256_setzero_pd();


int i, j, k;

// #pragma omp parallel for schedule(static)
for (i = 0; i < size; i++)
{
    for (j = 0; j < size; ++j)
    {
        //Stores one element in mat1 and use it in all computations needed before proceeding
        //Stores as vector to increase computations per cycle
        vec_mat1 = _mm256_set1_pd(mat1[i][j]);
#pragma omp parallel for
        for (k = 0; k < size; k += 8)
        {
            vec_mat2 = _mm256_loadu_pd((void*)&mat2[j][k]); //Stores row of second matrix (eight in each iteration)
            vec_multi_res = _mm256_loadu_pd((void*)&result[i][k]); //Loads the result matrix row as a vector
            vec_multi_res = _mm256_add_pd(vec_multi_res ,_mm256_mul_pd(vec_mat1, vec_mat2));//Multiplies the vectors and adds to th the result vector

            _mm256_storeu_pd((void*)&result[i][k], vec_multi_res); //Stores the result vector into the result array
        }
    }
    }
}

我在编译中没有遇到任何错误,但是当我执行程序时,我得到了一个分段错误(核心转储)。 通过调试,我注意到核心在vec_mat2 = _mm256_load_pd((void*)&mat2[j][k])这条指令处以一定大小(大于 100)转储。请按照您的说明查看下面的更新代码。

void mat_mul_pl(int size, double **mat1, double **mat2, double **result)
{

int i, j, k;

#pragma omp Parallel shared(vec_mat1,vec_mat2,vec_multi_res) private(i,j,k)
{

#pragma omp for schedule(static)
    for (i = 0; i < size; i++)
    {       
        for (j = 0; j < size; ++j)
        {
            __m256d vec_mat1 = _mm256_setzero_pd(); 
            vec_mat1 = _mm256_set1_pd(mat1[i][j]);
            for (k = 0; k < size; k += 4)
            { 
                __m256d vec_multi_res = _mm256_setzero_pd(); 
                __m256d vec_mat2 = _mm256_setzero_pd();
                vec_mat2 = _mm256_load_pd((void*)&mat2[j][k]); 
                vec_multi_res = _mm256_load_pd((void*)&result[i][k]); 
                vec_multi_res = _mm256_add_pd(vec_multi_res ,_mm256_mul_pd(vec_mat1, vec_mat2));
                _mm256_store_pd((void*)&result[i][k], vec_multi_res);
            } 
        }
    }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM