Quick eureka before I sleep.

The bulk of processing is in the `sum` function for both Python and Nim, as 
@Stefan_Salewski you should store the previous result because right now the 
algorithm is doing an extra useless pass on `farray`, furthermore this relies 
on the initialization of that empty array being all zero.

Regarding the speed difference between Python and Numpy, I can recover those 
2.4x speed difference by compiling the Nim code with `nim c -r -d:release 
--passC:-march=native --passC:-ffast-math build/prices_new.nim`.

**Slowness explanation**

The explanation is a bit complex, it starts from the fact that floating point 
addition is not associative, i.e. `(a + b) + c != a + (b + c)` due to floating 
point rounding. That means that the compiler cannot change the order or your 
computation without changing the program, `-ffast-math` allows the compiler to 
do so.

The second part is that at a low-level each instruction have a latency, 
floating-point addition have 3 to 5 cycle latency depending on your CPU (a 4GHz 
CPU executes 4 billions cycles per second). Latency does not impact 
instructions on independent data but in your case, a sum reuse old data so in a 
vacuum sum is 3-5 times slower than an elementwise addition.

The way around that is to keep as many accumulator as your addition latency (3 
if latency of 3) and sum them at the end, this is what the compiler does with 
`-ffast-math` because otherwise he is not allowed to reorder computation.

Laser, the future revamped backend of Arraymancer has [several benchmarks of 
this 
effect](https://github.com/numforge/laser/blob/bf751f4bbec3d178cd3a80da73e446658d0f8dff/benchmarks/fp_reduction_latency/reduction_bench.nim)
 and a [sum 
implementation](https://github.com/numforge/laser/blob/bf751f4bbec3d178cd3a80da73e446658d0f8dff/laser/primitives/reductions.nim)
 that reaches the max performance possible (capped by RAM speed) without the 
need for `ffast-math` compile flag

**A warning about floating point**

The magnitude of your number is quite high and you are accumulating a lot of 
floating-point rounding error especially on your `psumsum`, which is in the 
order of `2.4^10`, you might not see in Python because it uses arbitrary 
precision floats (though Numpy does not)

Reply via email to