Disagree: I’m also using mmap and my times are way more consistent. Just tried several times right now and constantly get ~2.98s (3.54s for your code).
In the measurements.txt I have 413 different cities (the command is still running, but that’s the way how it was created) and this is exactly that number I obtain in my case.
Final version is here. <6s on 4 cores, on my XPS13 laptop I’m happy with it.
If you run it with fortran-13 it doesn’t seem to have the thread stall problem.
Cool, congrats! On my PC it takes ~3.2 s (gfortran 11.4). I tried it with ifx and it crashes (which actually can mean not a standard behavior of your program; I saw gfortran was more forgiving).
Do I understand correctly that for the hash table you do not use a regular array, but create … who is it … linked list? Also in your main program you define type(row_ptr) :: hash_tbl(parts, hash_tbl_size). It might be faster if you re-arrange the dimensions, in fortran we have many-dimensional arrays stored in the memory not as in C.
Thank you for trying it! Its fastest with Fortran 13, so that may speed it up a little on your machine. Also setting integer :: parts = 16 to either the number of cores you have (if no hyperthreading) or to twice the number of cores (if hyper threading). to be twice the number of cores: that makes quite a big difference.
I’ve coded a long time (~20 years), but this is my first Fortran program I was delighted by how easy the language is to learn compared to my recent experiments (Prolog, Haskell). I haven’t tried it with ifx: I’ll give it a go and try to standardise it. I’m not surprised it doesn’t work under ifx because of the big number stuff in the hashing function, integer kinds, and the use of the transfer function: different assumptions about endians, wrapping behaviour, etc would produce different results.
No, it uses a regular array. I have an array of type(row_ptr):
type :: row_ptr
type(row), pointer :: p => null()
end type row_ptr
That allows me to address the content of individual cells.