Использование кэша и производные типы

Я новичок в профилировании кода с помощью valgrind и cachegrind, и недавно я начал использовать эти инструменты, чтобы посмотреть, как мой код работает с использованием кэша. Я обнаружил, что простое выражение if, по-видимому, вызывает пропадание кэша почти каждый раз, когда он выполняется. В качестве примера я использую следующие производные типы в моей программе на Фортране:

type :: particle
    real(pr), dimension(3) :: r = 0.0_pr ! position
    real(pr), dimension(3) :: p = 0.0_pr ! momentum
end type particle

type :: rcell ! position cell
    integer, dimension(6) :: bpoints = 0 ! cell grid points
    integer :: np = 0 ! number of particles in cell
    type(particle), dimension(50) :: parts ! particles in cell
end type rcell

type(rcell), dimension(:), allocatable :: rbin ! position space bins
allocate(rbin(100))

Этот пример представляет собой 100 ячеек в пространстве позиций, которые могут содержать до 50 частиц, описываемых их положением и импульсом. Код использует простой движитель частиц для обновления положения и импульса частиц на заданном временном шаге. Чтобы реализовать это, я использую цикл, подобный следующему:

do i = 1, numcells
    if (rbin(i)%np == 0) cycle ! skip cells with no particles
    ...
end do

Включив оператор if, я решил, что я буду ускорять код, циклически повторяя цикл, когда в данной ячейке нет частиц. Однако я провел некоторое профилирование своего кода, используя valgrind с инструментом cachegrind, и обнаружил, что это простое выражение if почти всегда приводит к пропаданию кэша. Ниже приведен пример результатов этого оператора if с использованием cg_annotate с --auto=yes опция включена:

Ir: 21,600,000
I1mr: 0
ILmr: 0
Dr: 4,320,000
D1mr: 4,319,057
DLmr: 4,318,979
Dw: 0
D1mw: 0
DLmw: 0

Это кажется пропуском кеша почти каждый раз, когда он выполняется. Я часто делаю это в своем коде, когда зацикливаюсь на ячейках, и я думаю, что это вызывает значительное замедление. Является ли это следствием использования производных типов? Есть ли способ улучшить использование кэша здесь, или с производными типами в целом?

Для полноты я компилирую с помощью gfortran 4.8.3 и использую следующие флаги: -g -O3 -ffast-math -mcmodel=medium -fdefault-real-8

0 ответов

Другие вопросы по тегам