Hello Jakob,
Thank you, that seems logical since log2 should be more natural (faster?) to
compute log2() than log(). But what you describe is almost exactly of what I
see with "GCC: (GNU) 13.4.0".
For this code snipet:
uint8_t i;
double j = 0.0;
for (i = 1 ; i <= 10 ; i++)
j += log2((double)i);
The assembler shows this for the loop (gcc -O3 -S test.c):
.L2:
movzbl %bl, %eax
pxor %xmm0, %xmm0
addl $1, %ebx
cvtsi2sdl %eax, %xmm0
call log
divsd %xmm7, %xmm0
addsd %xmm0, %xmm6
cmpb $11, %bl
jne .L2
So it uses the log function in place of the log2 function with the argument in
xmm0 and the result in xmm0, and then divides the result by log2(e), which is
in xmm7. (The sum (j) is accumulated in xmm6.)
From an efficiency standpoint, I find this to be...disappointing. Log2 should
be easier to compute, the divide should not be needed, and xmm7 gets
unnecessarily consumed to store the conversion constant. I even question
whether the pxor is necessary.
Interestingly, if I compile with g++ -O3 -S test.c, I get something more
reasonable:
.L2:
movzbl %bl, %eax
pxor %xmm0, %xmm0
addl $1, %ebx
cvtsi2sdl %eax, %xmm0
call log2
addsd %xmm0, %xmm6
cmpb $11, %bl
jne .L2
So part of the solution may be for this old guy to figure out what it takes to
make the rest of his code c++ compliant.
Best Regards,
Kennon
> On 01/21/2026 6:33 PM PST Jakob Bohm via Cygwin <[email protected]> wrote:
>
>
> On 18/01/2026 21:00, KENNON J CONRAD via Cygwin wrote:
> > Hello,
> >
> > I am not an experienced cygwin user but have been using it to compile
> > code on Windows (gcc), so I may be leaving out some key details. My issue
> > is that for every log2 call in my code there is a divide that follows a log
> > library call in the assembly code. It appears to be related to these lines
> > in math.h:
> >
> > #if !defined(__cplusplus)
> > #define log2(x) (log (x) / _M_LN2)
> > #endif
> >
> > My questions are: If log(x) is used, wouldn't it be faster to multiply by
> > constant (1/LN2) instead of divide by constant (LN2)? And wouldn't it be
> > even more efficient to compute log2 directly instead of computing the
> > natural log and then converting it to log2?
> >
> > I realize this is not a "bug", it just doesn't seem very optimal from an
> > speed standpoint.
> Please note, that on the x86 and x86_64 platforms, the natural log
> function log() is often implemented in terms of the intrinsic log2()
> function multiplied by log(2), which is done by the instruction FYL2X,
> thus preferably the x86 family port of newlib should include an
> intrinsic or inline implementation such as something doing the
> assembler sequence FLD1, FXCH, FYL2X, which takes the arg in ST(0)
> and returns the log2() result in ST(0). For targets that tend to
> run the floating point subsystem in a mode other than traditional
> x87, perhaps finding similar inline code for SSE or MMX would be
> needed. Other libc implementations may include the needed code in
> gcc-compatible format already.
>
> Enjoy
>
> Jakob
> --
> Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
> Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
> This public discussion message is non-binding and may contain errors.
> WiseMo - Remote Service Management for PCs, Phones and Embedded
>
>
> --
> Problem reports: https://cygwin.com/problems.html
> FAQ: https://cygwin.com/faq/
> Documentation: https://cygwin.com/docs.html
> Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple