prolong3:提升cache命中率

This commit is contained in:
2026-03-02 10:31:46 +08:00
parent 672b7ebee2
commit 47f91ff46f

View File

@@ -1959,7 +1959,7 @@
real*8 :: tmp_xyz_line(extc(1)) ! 存储整条 X 线上完成 Y 向融合后的结果 real*8 :: tmp_xyz_line(extc(1)) ! 存储整条 X 线上完成 Y 向融合后的结果
real*8 :: v1, v2, v3, v4, v5, v6 real*8 :: v1, v2, v3, v4, v5, v6
integer :: ic, jc, kc, ix_offset,ix,iy,iz integer :: ic, jc, kc, ix_offset,ix,iy,iz
real*8 :: res_line
if(wei.ne.3)then if(wei.ne.3)then
write(*,*)"prolongrestrict.f90::prolong3: this routine only surport 3 dimension" write(*,*)"prolongrestrict.f90::prolong3: this routine only surport 3 dimension"
write(*,*)"dim = ",wei write(*,*)"dim = ",wei
@@ -2081,6 +2081,32 @@
py = piy(j) py = piy(j)
jc = ciy(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 向插值 ! 1. 【降维Z 向】对当前 (j,k) 相关的 6 条 Y 偏置线进行 Z 向插值
! 结果存入 tmp_yz(x_index, y_offset) ! 结果存入 tmp_yz(x_index, y_offset)
do jj = 1, 6 do jj = 1, 6
@@ -2101,7 +2127,7 @@
WC(3,py)*tmp_yz(ii, 3) + WC(4,py)*tmp_yz(ii, 4) + & 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) WC(5,py)*tmp_yz(ii, 5) + WC(6,py)*tmp_yz(ii, 6)
end do end do
#endif
! 3. 【降维X 向】最后在最内层只处理 X 方向的 6 点加权 ! 3. 【降维X 向】最后在最内层只处理 X 方向的 6 点加权
! 此时每个点的计算量从原来的 200+ 次乘法降到了仅 6 次 ! 此时每个点的计算量从原来的 200+ 次乘法降到了仅 6 次
do i = imino, imaxo do i = imino, imaxo