michael-hartmann / caps

The Casimir Effect in the plane-sphere geometry.
GNU General Public License v2.0
4 stars 1 forks source link

Why are there lookup tables for `log` in the code? #157

Closed eschnett closed 4 years ago

eschnett commented 4 years ago

I briefly looked at the code, and I find a large lookup table in logfac.c that seems to contain the values for log(n) for n from 0 to 65535. Why are these tables there? Is this actually faster than calling the log function?

https://github.com/openjournals/joss-reviews/issues/2011

michael-hartmann commented 4 years ago

The lookup tables are used for the functions logi, lfac and lfac2 which are used in the files src/integration.c, src/libcaps.c, and src/plm.c.

Some time ago I was checking the speedup using a lookup table and found a significant performance gain for some special cases. I will check again if this is still the case.

michael-hartmann commented 4 years ago

The lookup table for the log function is only for integer arguments, log(0), log(1), log(2)... This is a cheap lookup in an array while the log function of the libc has to do the full calculation and has to check all the corner cases (is the argument INF or NAN...). The function logi is used in the function lfac(n) which computes the logarithm of the faculty for integer arguments n. lfac is used in a lot of places throughout the code. The function uses a lookup table for small values (n < 1024) and an asymptotic expansion for larger values. In the asymptotic expansion logi is used instead of log.

I have used the test cases caps_logdetD and caps_logdetD from the test suite for a small benchmark. The computation of the determinants dominates the execution time when computing the Casimir free energy by far. Therefore, I think the two tests are a useful indicator for a speedup. In general, the speedup will depend on the chosen parameters. But my motivation is rather to see if there is a significant speedup than assessing how big it actually is.

I consider three cases: With loopup tables for logi and lfac, no lookup tables at all, and only a lookup table for lfac. Here are the results I get on my machine:

test case with lookup tables without lookup tables only lookup table for lfac
caps_logdetD 510s 613s 547s
caps_logdetD0 10s 16s 10s

These results are consistent with what I remember from the last time I measured the speedup. I think the speedup justifies the somewhat ugly lookup tables. My conclusion is that logi is slightly faster than log and the main speedup comes from using an asymptotic expansion in lfac avoiding to call lgamma.

eschnett commented 4 years ago

Thanks for the detailed answer!

If you don't like the tables in the code, then you could calculate them at startup.