C 不带折叠指令的OpenMP嵌套for循环
我正在尝试用OpenMP实现矩阵乘法 我发现嵌套for循环中通常使用collapse指令 所以我也使用了下面的折叠。(此代码属于神经网络中的前馈)C 不带折叠指令的OpenMP嵌套for循环,c,openmp,collapse,C,Openmp,Collapse,我正在尝试用OpenMP实现矩阵乘法 我发现嵌套for循环中通常使用collapse指令 所以我也使用了下面的折叠。(此代码属于神经网络中的前馈) for(i=0;inum_layer-1;i++){ #用于num_线程的pragma omp并行(线程)私有(j)折叠(2) 对于(j=0;jmini_batch_size;j++){ 对于(k=0;klayer_size[i+1];k++){ #pragma omp simd缩减(+:总和) 对于(l=0;llayer_size[i];l++){
for(i=0;inum_layer-1;i++){
#用于num_线程的pragma omp并行(线程)私有(j)折叠(2)
对于(j=0;jmini_batch_size;j++){
对于(k=0;klayer_size[i+1];k++){
#pragma omp simd缩减(+:总和)
对于(l=0;llayer_size[i];l++){
总和=总和+神经元(净,i,j,l)*重量(净,i,l,k);
}
ZS(净,i+1,j,k)=和+偏差(净,i+1,k);
神经元(net,i+1,j,k)=乙状结肠(ZS(net,i+1,j,k));
总和=0.0;
}
}
}
但我想知道的是,有没有办法实现并行化而不崩溃?我也尝试了下面的方式,但是表现在我的期望之下
omp_set_nested(1);
for (i = 0; i < net->num_layer-1; i++) {
#pragma omp parallel for num_threads(net->mini_batch_size) private(j)
for (j = 0; j < net->mini_batch_size; j++) {
#pragma omp parallel for num_threads(net->layer_size[i+1]) private(j, k)
for (k = 0; k < net->layer_size[i+1]; k++) {
#pragma omp simd reduction(+:sum)
for (l = 0; l < net->layer_size[i]; l++) {
sum = sum + NEURON(net, i, j, l) * WEIGHT(net, i, l, k);
}
ZS(net, i+1, j, k) = sum + BIAS(net, i+1, k);
NEURON(net, i+1, j, k) = sigmoid(ZS(net, i+1, j, k));
sum = 0.0;
}
}
}
omp\u set\u嵌套(1);
对于(i=0;inum_layer-1;i++){
#用于num_线程(net->mini_batch_size)private(j)的pragma omp parallel
对于(j=0;jmini_batch_size;j++){
#pragma omp并行用于num_线程(net->layer_size[i+1])私有(j,k)
对于(k=0;klayer_size[i+1];k++){
#pragma omp simd缩减(+:总和)
对于(l=0;llayer_size[i];l++){
总和=总和+神经元(净,i,j,l)*重量(净,i,l,k);
}
ZS(净,i+1,j,k)=和+偏差(净,i+1,k);
神经元(net,i+1,j,k)=乙状结肠(ZS(net,i+1,j,k));
总和=0.0;
}
}
}
在线程中,变量为100常量。它将在以后进行优化,但我现在修复了它。而且,性能的结果是,使用collpase时,0.75秒,没有崩溃时,25秒
因此,无论如何,请告诉我是否有任何方法可以在不使用collpase的情况下实现嵌套循环,从而获得比崩溃更好的性能。使用collpase,0.75秒,而不使用崩溃,表面上是25秒,这在性能上是一个显著的差异。那些数字正确吗?是的,是真的。在你评论“我正试图用OpenMP实现矩阵乘法”之后,我又这么做了。为什么?矩阵乘法看起来很容易,但获得最佳性能绝非易事。你最好把时间花在找出如何使用BLAS为你做这件事上。(英特尔MKL现在是免费的,并将在适当的情况下在内部并行运行)。(FWIW我为英特尔工作,但不是在MKL上。)@JimCownie谢谢你的评论。首先,我已经用MKL实现了。我想弄明白的是,openmp比MKL快,collpase为0.75秒,表面上没有崩溃,为25秒,这是一个显著的性能差异。那些数字正确吗?是的,是真的。在你评论“我正试图用OpenMP实现矩阵乘法”之后,我又这么做了。为什么?矩阵乘法看起来很容易,但获得最佳性能绝非易事。你最好把时间花在找出如何使用BLAS为你做这件事上。(英特尔MKL现在是免费的,并将在适当的情况下在内部并行运行)。(FWIW我为英特尔工作,但不是在MKL上。)@JimCownie谢谢你的评论。首先,我已经用MKL实现了。我想弄明白的是,openmp比MKL更快
omp_set_nested(1);
for (i = 0; i < net->num_layer-1; i++) {
#pragma omp parallel for num_threads(net->mini_batch_size) private(j)
for (j = 0; j < net->mini_batch_size; j++) {
#pragma omp parallel for num_threads(net->layer_size[i+1]) private(j, k)
for (k = 0; k < net->layer_size[i+1]; k++) {
#pragma omp simd reduction(+:sum)
for (l = 0; l < net->layer_size[i]; l++) {
sum = sum + NEURON(net, i, j, l) * WEIGHT(net, i, l, k);
}
ZS(net, i+1, j, k) = sum + BIAS(net, i+1, k);
NEURON(net, i+1, j, k) = sigmoid(ZS(net, i+1, j, k));
sum = 0.0;
}
}
}