这是神经网络上反向传播算法代码的一部分。
在我们的例子中,我们想要并行化for(pt = 0; pt< N_PT_pair; pt ++)循环,for(epoch = 0; epoch< MaxEpoch; epoch ++)不能并行化。
initialize W1[ ] [ ] and W2[ ][ ] with random values
for(epoch=0; epoch<MaxEpoch; epoch++)
dW1[ ][ ]=0.0; dW2[ ][ ]=0.0; //sum of weight corrections
sse = 0; // Sum of square of errors
for( pt=0; pt<N_PT_pair; pt++)
input = pattern[pt];
compute output // procedure as above
compare target[pt] and output and
compute dW2[ ][ ] += ... // procedure to be described
compute dW1[ ][ ] += ... // procedure to be described
for(k=1; k<=Noutput; k++)
sse+=pow((target[pt][k]-output[k]),2);
end pt for loop
cout << "mean square error" << sse/N_PT_pair;
W1[ ][ ] += rate*dW1[ ][ ]
W2[ ][ ] += rate*dW2[ ][ ]
end epoch for loop
这些是分配和解除分配数组的代码
double** allocate_matrix(int rows,int cols)
{
double **a;
a = new double*[rows];
if(a==NULL){cout<<"matrix allocation failed"<<endl;exit(-1);}
for (int j=0;j<rows;j++){
a[j] = new double[cols];
if(a[j]==NULL) {cout<<"matrix allocation failed"<<endl;exit(-1);}
}
return a;
}
int deallocate_matrix(double**a,int rows)
{
for(int i=0;i<rows;i++)
delete [] a[i];
delete [ ] a;
return 0;
}
你可以帮我们并行化代码吗?
答案 0 :(得分:1)
如果内部循环中的迭代彼此独立,那么您可以简单地从一个OpenMP构造开始:
#pragma omp parallel for private(input,k) reduction(+:sse)
for( pt=0; pt<N_PT_pair; pt++)
input = pattern[pt];
compute output // procedure as above
compare target[pt] and output and
compute dW2[ ][ ] += ... // procedure to be described
compute dW1[ ][ ] += ... // procedure to be described
for(k=1; k<=Noutput; k++)
sse+=pow((target[pt][k]-output[k]),2);
end pt for loop
如果在多次迭代中没有更新dW1
或dW2
的元素,那么这将非常有用,否则将需要原子访问并且会破坏性能(OpenMP仍然不支持减少C / C ++中的数组。
如果您有大量的网络权重,您也可以以相同的方式并行化乘法。
并行区域可以进一步移出外部循环以减少OpenMP开销,single
或master
OpenMP指令可用于隔离应该只在单个线程中运行的代码
为了让编译器理解#pragma omp
指令,您必须启用OpenMP支持。具体如何是编译器具体完成的:
-fopenmp
代表GCC -openmp
for Intel C / C ++ Compiler -xopenmp
for Oracle Solaris Studio