Add some optimizations#4
Conversation
|
Positive:
Problematic:
Conclusion: The PR sacrifices performance for code aesthetics in a cryptographic low-level library where performance is the primary goal. The race condition is a real bug. For a project like libdvbcsa, which is designed for maximum throughput, I would not merge this PR as-is. The deduplication of |
Recommendation: Reduce duplication without sacrificing performance1.
|
5c8a722 to
b57464b
Compare
|
Understood, quite important notes.
I rewrote the proposal of changes. Then I have done some benchmarking (x86_64/ssse3/avx2/native) but in any case I was unable to observe performance drops - no more than 0.2%. Tested only on x86_64 cpu. |
|
Let me check your changes later. Be aware of we are using this lib with aarch64, arm and mipsel architectures in embedded systems. |
|
The updated PR removes the
So check #5 |
Inspired by PR oe-mirrors#4 (lukasz1992), this commit eliminates duplicated code across the stream cipher kernel and key scheduling functions while preserving the original runtime performance characteristics. Stream cipher kernel (dvbcsa_bs_stream_kernel.inc): - Replace the #ifdef DVBCSA_BS_STREAM_KERNEL_INIT / #else / #endif double-include trick with a single unified function _dvbcsa_bs_stream_cipher_kernel(const int init, regs). - The function is marked static DVBCSA_INLINE inline, which maps to __attribute__((always_inline)) on GCC. Combined with the macro wrappers that pass literal constants (0 or 1), the compiler is guaranteed to inline and eliminate the dead branches via constant propagation — producing identical machine code to the original two-function approach. - The sbox0 computation (4x unrolled Z/E carry chain) is intentionally kept unrolled. Extracting it into a loop function would break the regs->r "ultimate carry" calculation, which depends on tmp1/tmp3 values from the final iteration remaining in scope. Stream cipher includes (dvbcsa_bs_stream.c): - The .inc file is now included only once instead of the previous define/undef/include-twice pattern. Kernel dispatch macros (dvbcsa_bs_stream_kernel.h): - dvbcsa_bs_stream_cipher_kernel_init(regs) and dvbcsa_bs_stream_cipher_kernel(regs) are now macros that call _dvbcsa_bs_stream_cipher_kernel with compile-time constant 1 or 0. Key scheduling (dvbcsa_key.c): - dvbcsa_key_schedule_block() now delegates to dvbcsa_key_schedule_block_ecm(0, cw, kk), removing the duplicated loop body. Little-endian load (dvbcsa_pv.h): - dvbcsa_load_le64(p) is now a macro expanding to dvbcsa_load_le64_ecm(0, p). The compiler sees ecm=0 != 4 at compile time and eliminates the csa_block_perm_ecm lookup path entirely. Co-Authored-By: lukasz1992 <lukasz1992@users.noreply.github.com>
Inspired by PR oe-mirrors#4 (lukasz1992), this commit eliminates duplicated code across the stream cipher kernel and key scheduling functions while preserving the original runtime performance characteristics. Stream cipher kernel (dvbcsa_bs_stream_kernel.inc): - Replace the #ifdef DVBCSA_BS_STREAM_KERNEL_INIT / #else / #endif double-include trick with a single unified function _dvbcsa_bs_stream_cipher_kernel(const int init, regs). - The function is marked static DVBCSA_INLINE inline, which maps to __attribute__((always_inline)) on GCC. Combined with the macro wrappers that pass literal constants (0 or 1), the compiler is guaranteed to inline and eliminate the dead branches via constant propagation — producing identical machine code to the original two-function approach. - The sbox0 computation (4x unrolled Z/E carry chain) is intentionally kept unrolled. Extracting it into a loop function would break the regs->r "ultimate carry" calculation, which depends on tmp1/tmp3 values from the final iteration remaining in scope. Stream cipher includes (dvbcsa_bs_stream.c): - The .inc file is now included only once instead of the previous define/undef/include-twice pattern. Kernel dispatch macros (dvbcsa_bs_stream_kernel.h): - dvbcsa_bs_stream_cipher_kernel_init(regs) and dvbcsa_bs_stream_cipher_kernel(regs) are now macros that call _dvbcsa_bs_stream_cipher_kernel with compile-time constant 1 or 0. Key scheduling (dvbcsa_key.c): - dvbcsa_key_schedule_block() now delegates to dvbcsa_key_schedule_block_ecm(0, cw, kk), removing the duplicated loop body. Little-endian load (dvbcsa_pv.h): - dvbcsa_load_le64(p) is now a macro expanding to dvbcsa_load_le64_ecm(0, p). The compiler sees ecm=0 != 4 at compile time and eliminates the csa_block_perm_ecm lookup path entirely. Co-Authored-By: lukasz1992 <lukasz1992@users.noreply.github.com>
22c558a to
3ba82b6
Compare
3ba82b6 to
18ec015
Compare
|
Thanks, it looks good. Oops, have not properly copied the correct version. Just updated. In that case let me send only one commit, as you already put the rest in #5 (I put your commit also here, to avoid conflicts) |
Mainly to reduce code size (and binary size).