On today’s masochism section… we find the nearest power of two in Assembly!
Macro PowerOfTwo( _num_ )
!MOV Eax, [v_#_num_]
!SUB Eax, 1
!PowerOfTwo_Loop_#_num_:
!MOV Ecx, Eax
!ADD Eax, 1
!AND Ecx, Eax
!JNZ PowerOfTwo_Loop_#_num_
!MOV [v_#_num_], Eax
EndMacro
Truth be told I was looking for some old libraries I wrote a while back and I stumbled upon that code. It made me chuckle so of course I had to share it. The reason I laughed was because, well… Who would really need to optimize such a routine?; in those days I was suffering from a severe case of premature-optimizationitis.
However, compared to the normal method which follows:
Procedure.i NearestPow2( Value.i )
ProcedureReturn Pow( 2, Int((Log( Value ) / Log(2)) + 0.5) )
EndProcedure
The ASM routine is about 25 times faster (I benchmarked the code itself without the procedure to be fair, otherwise it would’ve been 55 times faster!)
So, while unnecessary it still proves a point — You can always optimize your code for speed. However, the cost is clear… readability!
I guess it’s worth stating the obvious in this case: Always benchmark your code and find a balance when it comes to optimization, only optimize your bottlenecks. Don’t waste time in small details unless the reward is worth the time.
Cheers!
PS: Since the PB pre-processor is case sensitive (who would’ve known!) Remember that you must pass the macro the same label your variable has, also because we define a label this means we can only call the routine in one place for one particular variable. That however was not an issue with my code, so it never bothered me.