Блокировка кэша и предварительная выборка - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь проверить эффективность ручной блокировки кэша или оптимизации циклического разбиения, которая была применена к некоторой рутине научного кода на Фортране. Что касается выбора размера тайлов, я использовал алгоритм, основанный на классической оценке различных линий. Я использую Intel Fortran Compiler 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 (что должно быть следствием флага оптимизации -3opt-prefetch = 3 O3), но я бы знал, смогу ли я продолжить оптимизацию с блокировкой кэша. Я пробовал какую-то ручную предварительную загрузку ПО, например:

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

но это, похоже, не помогает мне. Любые предложения будут очень благодарны.

С уважением.

...