我试图测试已应用于某些Fortran科学代码例程的手动缓存阻止或循环平铺优化的有效性。关于平铺尺寸选择,我使用了基于经典的不同线估计的算法。我正在使用英特尔Fortran编译器ifort 18.0.1(2018)
使用O3 xHost编译标志编译代码。要观察基本版本和平铺版本之间的任何加速,我必须将预取级别切换为2(通过使用-qopt-prefetch = 2)。通过这样做,我实际上获得了27%的加速(24秒对33秒)。使用正常的O3 xHost时,执行时间仍然未得到改善(20秒) - 所以我在基础和平铺之间没有区别。
一个简单的循环嵌套如下,基本版本:
DO jk = 2, jpkm1 ! Interior value ( multiplied by wmask)
DO jj = 1, jpj
DO ji = 1, jpi
zfp_wk = pwn(ji,jj,jk) + ABS( pwn(ji,jj,jk) )
zfm_wk = pwn(ji,jj,jk) - ABS( pwn(ji,jj,jk) )
zwz(ji,jj,jk) = 0.5 * ( zfp_wk * ptb(ji,jj,jk,jn) + zfm_wk * ptb(ji,jj,jk-1,jn) ) * wmask(ji,jj,jk)
END DO
END DO
END DO
和优化版本:
DO jltj = 1, jpj, OBS_UPSTRFLX_TILEY
DO jk = 2, jpkm1
DO jj = jltj, MIN(jpj, jltj+OBS_UPSTRFLX_TILEY-1)
DO ji = 1, jpi
zfp_wk = pwn(ji,jj,jk) + ABS( pwn(ji,jj,jk) )
zfm_wk = pwn(ji,jj,jk) - ABS( pwn(ji,jj,jk) )
zwz(ji,jj,jk) = 0.5 * ( zfp_wk * ptb(ji,jj,jk,jn) + zfm_wk * ptb(ji,jj,jk-1,jn) ) * wmask(ji,jj,jk)
END DO
END DO
END DO
END DO
为什么我不能观察O3 xHost正常运行的任何加速?问题应该是O3引入的积极SW预取(应该是-qopt-prefetch = 3 O3优化标志的影响),但我知道是否可以进一步优化缓存阻塞。我尝试了一些像这样的手工SW预取:
DO jltj = 1, jpj, OBS_UPSTRFLX_TILEY
DO jk = 2, jpkm1
DO jj = jltj, MIN(jpj, jltj+OBS_UPSTRFLX_TILEY-1)
DO ji = 1, jpi
zfp_wk = pwn(ji,jj,jk) + ABS( pwn(ji,jj,jk) )
zfm_wk = pwn(ji,jj,jk) - ABS( pwn(ji,jj,jk) )
zwz(ji,jj,jk) = 0.5 * ( zfp_wk * ptb(ji,jj,jk,jn) + zfm_wk * ptb(ji,jj,jk-1,jn) ) * wmask(ji,jj,jk)
IF(jk== jpkm1 .AND. jj == MIN(jpj, jltj+OBS_UPSTRFLX_TILEY-1)-2) THEN
CALL mm_prefetch(pwn(1,jltj+OBS_UPSTRFLX_TILEY,1), 1)
CALL mm_prefetch(zwz(1,jltj+OBS_UPSTRFLX_TILEY,1), 1)
CALL mm_prefetch(ptb(1,jltj+OBS_UPSTRFLX_TILEY,1,jn), 1)
CALL mm_prefetch(wmask(1,jltj+OBS_UPSTRFLX_TILEY,1), 1)
ENDIF
END DO
END DO
END DO
END DO
但这似乎对我没有帮助。任何建议都会非常感激。
最好的问候。