时域仿真中的内存管理

计算科学 并行计算 正则 内存管理
2021-12-25 09:22:19

我使用 OpenMP 和 Fortran 2003 开发了一个并行时域 DAE 仿真软件。主要算法是:

while t<time_horizon do
   X_1=X
   while not converged do
      !$OMP PARALLEL DO
         Solve sub-domain DAE using a portion on X and X_1 to get DeltaX
         Correct X=X+DeltaX
      !$OMP END PARALLEL DO
   end
   t=t+h
end

X 是状态变量向量,X_1 是用于离散化算法(梯形方法)的前一个时间步的向量。

顺序实现分析表明,内存复制占用了 15% 的计算时间,这是相当大的数量......

我试过了:

!$omp parallel workshare
   X_1=X
!$omp end parallel worshare

和:

!$omp parallel
   i=omp_get_thread_num()
   X_1(i*length/num_threads+1:(i+1)*length/num_threads)= X(i*length/num_threads+1:(i+1)*length/num_threads)
!$omp end parallel

这有一点帮助(下降到 13%),但作用不大……有什么想法吗?还有什么方法可以保存历史吗?我将所有子域的 X 保留为一个向量,因为它更易于处理(应用无限范数、复制等)。我应该为每个子域将它分成一个吗?

提前致谢!

1个回答

您不需要复制状态向量。假设您要存储两个副本 X1 和 X2,您可以让并行区域首先在 X1 上工作,然后在下一次迭代中在 X2 上工作。在 Fortran 中,一种简单的方法是将并行区域移动到子程序中,并从主循环中调用它:

while t<time_horizon do
   call evolve(X1, X2)
   t=t+h
   if (t>=time_horizon) then
      "swap x1 and x2"
      exit
   end if
   call evolve(X2, X1)
   t=t+h
end while