Cache usage and derived types

159 Views Asked by At

I am new to profiling code with valgrind and cachegrind, and I recently started using these tools to see how my code was doing in regards to cache utilization. I found that a simple if-statement appears to cause a cache miss almost every single time it is executed. As an example, I make use of the following derived types in my Fortran program:

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))

This example represents a 100 cells in position space that could contain up to 50 particles described by their position and momentum. The code uses a simple particle mover to update position and momentum of the particles at a given time step. To implement this, I use a loop like the following:

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

By including the if-statement I figured that I would be speeding the code up by cycling the loop when there are no particles in a given cell. However, I did some profiling of my code using valgrind with the cachegrind tool and found that this simple if-statement almost always results in a cache miss. The following is an example of the results for this if-statement using cg_annotate with the --auto=yes option enabled:

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

This appears to be a cache miss almost every time it is executed. I do this a lot in my code when looping over cells, and I think it causing a major slow down. Is this a consequence of using derived types? Is there a way to improve the cache utilization here, or with derived types in general?

For completeness, I am compiling with gfortran 4.8.3 and using the following flags: -g -O3 -ffast-math -mcmodel=medium -fdefault-real-8

0

There are 0 best solutions below