diff --git a/AMSS_NCKU_source/prolongrestrict_cell.f90 b/AMSS_NCKU_source/prolongrestrict_cell.f90 index 8593cad..9074b26 100644 --- a/AMSS_NCKU_source/prolongrestrict_cell.f90 +++ b/AMSS_NCKU_source/prolongrestrict_cell.f90 @@ -1959,7 +1959,7 @@ real*8 :: tmp_xyz_line(extc(1)) ! 存储整条 X 线上完成 Y 向融合后的结果 real*8 :: v1, v2, v3, v4, v5, v6 integer :: ic, jc, kc, ix_offset,ix,iy,iz - + real*8 :: res_line if(wei.ne.3)then write(*,*)"prolongrestrict.f90::prolong3: this routine only surport 3 dimension" write(*,*)"dim = ",wei @@ -2081,6 +2081,32 @@ py = piy(j) jc = ciy(j) +! --- 步骤 1 & 2 融合:分段处理 X 轴,提升 Cache 命中率 --- + ! 我们将 ii 循环逻辑重组,减少对 funcc 的跨行重复访问 + do ii = 1, extc(1) + ! 1. 先做 Z 方向的 6 条线插值(针对当前的 ii 和当前的 6 个 iy) + ! 我们直接在这里把 Y 方向的加权也做了,省去 tmp_yz 数组 + ! 这样 funcc 的数据读进来后立即完成所有维度的贡献,不再写回内存 + + res_line = 0.0d0 + do jj = 1, 6 + iy = jc - 3 + jj + ! 这一行代码是核心:一次性完成 Z 插值并加上 Y 的权重 + ! 编译器会把 WC(jj, py) 存在寄存器里 + res_line = res_line + WC(jj, py) * ( & + WC(1, pz) * funcc(ii, iy, kc-2) + & + WC(2, pz) * funcc(ii, iy, kc-1) + & + WC(3, pz) * funcc(ii, iy, kc ) + & + WC(4, pz) * funcc(ii, iy, kc+1) + & + WC(5, pz) * funcc(ii, iy, kc+2) + & + WC(6, pz) * funcc(ii, iy, kc+3) ) + end do + tmp_xyz_line(ii) = res_line + end do + + + +#if 0 ! 1. 【降维:Z 向】对当前 (j,k) 相关的 6 条 Y 偏置线进行 Z 向插值 ! 结果存入 tmp_yz(x_index, y_offset) do jj = 1, 6 @@ -2101,7 +2127,7 @@ WC(3,py)*tmp_yz(ii, 3) + WC(4,py)*tmp_yz(ii, 4) + & WC(5,py)*tmp_yz(ii, 5) + WC(6,py)*tmp_yz(ii, 6) end do - +#endif ! 3. 【降维:X 向】最后在最内层只处理 X 方向的 6 点加权 ! 此时每个点的计算量从原来的 200+ 次乘法降到了仅 6 次 do i = imino, imaxo