joonicks/ptr64tohex
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
Source: https://github.com/joonicks/ptr64tohex This is an experiment in assembly/C programming trying to increase efficiency by reducing codesize or removing branches. When converting a binary to hex string, I figured out that its possible to do it with binary logic instead of if statements. Normally the code would be; a = ... & 0xF if (a > 9) char = 'A' - 10 + a; else char = '0' + a; But the if statement creates an unpredictable branch that tanks performance. With logic you can do the following instead (and the gcc compiler does a good job with); a = ... & 0xF char = '0' + c + ((unsigned)(9 - c) >> 29); -------------------------------------------------------------------------------------------------- The different implementations is as follows: x_libc: ~110-115 clock cycles Just a simple wrapper for libc sprintf("%016lX") c_noob: ~160 clock cycles What a noob might make without using any lookup table c_luta: ~22 clock cycles Based on a lookup table instead c_simp: ~25 clock cycles Simple loop based conversion using logic instead of lookup a = nibble & 15 char = ((((a + 6) & 16) >> 4) * 7) + a + '0'; c_nobr: ~9.5 clock cycles Branchless, all low nibbles then all high nibbles done at once gcc compiler uses extra instructions to improve speed c_simd: (by dzaima) ~4.5 clock cycles SIMD version using SSE instructions a_noob: ~160 clock cycles Equivalent to c_noob slightly tweaked non lookup a_bext: ~27 clock cycles Loop 1 nibble at a time using bextr instruction a_nobr: ~8 clock cycles Assembly version of c_nobr Better ordering of instructions could improve speed