1. 目标:探究嵌套循环 for 和 collapse 编程
2. 内容
(1). for 并行区默认对最近外层的循环控制变量私有,并对其划分并行,不必指明 private,内层循环体入口的循环控制变量声明及或定义[ for (int i=0;)]默认私有;如果在并行区外声明或定义的内层循环控制变量默认 shared,应显式 pravate该变量,否则可能导致线程数据竞争,结果错误。如下代码,应注意:
a. 使用collapse(3) ,C[r][c]的计算数据不同数据在不同线程之间,会造成数据竞争,计算错误;如果使用临界区,速度过慢。
void gemm_2 (int * A,int * B,long * C,int N,int NT)
{
struct timeval start,end;
float time;
gettimeofday (&start,NULL );
omp_set_num_threads (NT);
#pragma omp parallel for collapse(2) schedule(guided) proc_bind(close)
for (int r=0 ;r<N;r++)
{
for (int c=0 ;c<N;c++)
{
#if 0
for (int k=0 ;k<N;k++)
{
#pragma omp critical
C[r*N+c] += A[r*N+k] * B[k*N+c];
}
#else
long sum=0 ;
for (int k=0 ;k<N;k++)
sum += A[r*N+k] * B[k*N+c];
C[r*N+c] = sum;
#endif
}
}
gettimeofday (&end,NULL );
time = end.tv_sec-start.tv_sec+(end.tv_usec-start.tv_usec)/1e6 ;
printf ("func %s N %d threads_num %d sum %ld useSec %f\n" ,__func__,N,NT,sum (C,N),time);
}
(2). collapse(n),最外n层的循环控制变量默认私有。在并行区内声明的变量默认 pravite。如下是一个 collapse(2) + collapse(2) + reduction 的示例:
a. 外两层循环步进为4,影响每个循环控制变量在每个线程中的起始值。内两层步进量内部循环。
void gemm_8 (int * A,int * B,long * C,int N,int NT)
{
struct timeval start,end;
float time;
int r,c,k;
gettimeofday (&start,NULL );
omp_set_num_threads (NT);
#pragma omp parallel for collapse(2) private(r,c) schedule(guided) proc_bind(close)
for (r=0 ;r<N;r+=4 )
{
for (c=0 ;c<N;c+=4 )
{
#pragma omp parallel for collapse(2) schedule(guided) proc_bind(close)
for (int nr=0 ;nr<4 ;nr++)
{
for (int nc=0 ;nc<4 ;nc++)
{
long sum =0 ;
#pragma omp parallel for reduction(+:sum) schedule(guided) proc_bind(close)
for (int k=0 ;k<N;k++)
sum += A[(r+nr)*N+k] * B[k*N+c+nc];
C[(r+nr)*N+c+nc] = sum;
}
}
}
}
gettimeofday (&end,NULL );
time = end.tv_sec-start.tv_sec+(end.tv_usec-start.tv_usec)/1e6 ;
printf ("func %s N %d threads_num %d sum %ld useSec %f\n" ,__func__,N,NT,sum (C,N),time);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?