3 ms·
That was the main reason. It also means that you don't need to pass around (a pointer to) a big table of function pointers throughout all of your functions tha
by derf_ 8y ago
That was the main reason.
It also means that you don't need to pass around (a pointer to) a big table of function pointers throughout all of your functions that need to use accelerated routines. Instead you just pass a single integer index. But that is pretty minor.
It can be pretty similar to a switch in practice, but I think there are a few differences. One is function argument handling. Each version of an accelerated routine has to be an independent function, compiled in a separate compilation unit, because you have to limit the instruction sets available. So you will duplicate all of the function call setup overhead in each branch of the switch. This probably gets optimized away by a decent compiler. Even if it does, you still wind up essentially duplicating the function table at every call site. That does not seem likely to get optimized away. You could dispatch to a common thunk which selects the accelerated routine to call, but now you have two function calls instead of one. I am also not sure that switch statements handle the default case as cheaply as doing a single bitwise AND with a small, compile-time constant.
But if you have a use of function pointers that can be replaced by a simple switch statement, that is probably the better approach.
- pjmlp 8y agoYour approach is kind of how indirect function calls are implemented in WebAssembly, if I am not mistaken.