Locality, locality locality#
There are three “localities” that are important.
Locality of written code#
Things that depend on each other should be near each other in your actual code. If you have a function A which heavily uses B, put B beneath A. Then it’s easy to find when you’re developing.
Locality of objects in memory#
When doing a numerical calculation, you want everything you’re using to be close to each other in memory. The most extreme example of this is global parameters. Consider the following code
function a_big_sum(N)
total = 0
for i in 1:N
total += lattice_spacing^N
end
return total
end
function a_big_sum_2(N, lattice_spacing)
total = 0
for i in 1:N
total += lattice_spacing^N
end
return total
end
In a_big_sum
we make a total. The parameter lattice_spacing
is not defined in the function
so we need to make it a global parameter. Let’s do that and benchmark
global lattice_spacing = 0.2
@btime a_big_sum(1000)
# 67.166 μs (3000 allocations: 46.88 KiB)
On the other hand, in a_big_sum_2
, the parameter lattice_spacing
is define within the
function. It’s a keyword argument. So we can pass it to the function and calculate:
lattice_spacing = 0.2
@btime a_big_sum_2(1000, lattice_spacing)
# 17.166 μs (1 allocation: 16 bytes)
It’s four times as fast!! Wow. Why?? Well, it’s because the global variable is “far away” from everything else being used. Make sure you pass everything that it used in the function to the function.
Locality of calculation#
This is helpful for paralellisation. When you do a field theory calculation you want to keep the
calculation local. So when you calculate the energy at point i
, you want this to only depend
on a few other points nearby: i+1
and i-1
, and maybe some more. If you do this, your code
should be fast and it should be easy to paralellise. Find out more here.