whatyouhide / nimble_lz4

LZ4 compression for Elixir using Rust NIFs. 🗜
https://github.com/lz4/lz4
Apache License 2.0
28 stars 5 forks source link

Use DirtyCPU schedulers for NIFs #7

Closed L4vlet closed 1 year ago

L4vlet commented 1 year ago

The official Erlang documentation suggests that NIFs should not take longer than 1 ms to execute. Otherwise calls to native functions starting to interfere with the BEAM schedulers.

With compression and decompression execution time is directly dependent on the input size. I used existing benchmarks and found that 1 ms is exceeded at approximately 190Kb for compression and 260Kb for decompression. My local machine has the following specs:

Operating System: macOS
CPU Information: Apple M2 Max
Number of Available Cores: 12
Available memory: 32 GB
Elixir 1.14.5
Erlang 25.3.2.2

A separate set of schedulers comes with a penalty of around 10us per call if we can believe this article. Again, if we follow the author's footsteps and assume that overhear becomes bearable when it takes < 10% of execution time we will get our threshold around 16Kb for compression and 32Kb for decompression.

Taking into consideration that an average running environment (e.g. Kubernetes pod) has way less computational resources than my laptop, I believe that we can safely enable Dirty CPU Bound Schedulers since they will better serve overwhelming majority of use cases.

whatyouhide commented 1 year ago

This is fantastic, thank you @L4vlet 🙃