March 29, 2022
On Tue, Mar 29, 2022 at 01:58:46PM +0000, 12345swordy via Digitalmars-d wrote:
> On Tuesday, 29 March 2022 at 12:13:31 UTC, Adam D Ruppe wrote:
[...]
> > Murilo might not need a big number lib at all.
> > 
> > For astronomy, there's a good chance floating point will do the job.
> 
> That not going to work if you are comparing things that are extremely big with something that is extremely small here.
[...]

I think you got that wrong, floating is precisely designed for such comparisons. You can easily compare 1e+1000 with 1e-1000 without running into problems.

Where you might run into problems is if you *add* (or subtract) extremely small numbers from extremely big numbers. Or if you divide by extremely small numbers. Or in general perform operations that mix numbers of greatly unlike magnitudes.


T

-- 
Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG
March 29, 2022
On Tuesday, 29 March 2022 at 15:23:45 UTC, H. S. Teoh wrote:
> On Tue, Mar 29, 2022 at 01:58:46PM +0000, 12345swordy via Digitalmars-d wrote:
>> On Tuesday, 29 March 2022 at 12:13:31 UTC, Adam D Ruppe wrote:
> [...]
>> > Murilo might not need a big number lib at all.
>> > 
>> > For astronomy, there's a good chance floating point will do the job.
>> 
>> That not going to work if you are comparing things that are extremely big with something that is extremely small here.
> [...]
>
> I think you got that wrong, floating is precisely designed for such comparisons. You can easily compare 1e+1000 with 1e-1000 without running into problems.
>
> Where you might run into problems is if you *add* (or subtract) extremely small numbers from extremely big numbers. Or if you divide by extremely small numbers. Or in general perform operations that mix numbers of greatly unlike magnitudes.
>
>
> T

Yes, and Adam did take out a double indemnity with "might not" and "good chance". The long dormant physicist in me is curious to see an example calculation/formula from Murilo, and his hoped-for precision at the end.

March 29, 2022

On Tuesday, 29 March 2022 at 12:06:54 UTC, deadalnix wrote:

>

No, I picked the exact same toolchain on purpose so that the approach themselves can be compared.
both of the example above you THE EXACT SAME toolchain, the only different is the approach to 128 bits integers in the frontend.

To me it looked like you did a C++ vs D somewhere in the way. But instead you're just doing the backend calls.

Also speaks of a bunch of my own inexperience in the deeper matters, and why i usually abstain from a number of these conversations I'm not well versed in.

>

The CPU has a lot of instructions to help handle large integers. When you let the backend do its magic, it can leverage them. When you instead give it good old small integers code and it has to infer the meaning from it and reconstruct the large integers ops you meant to be doing and optimize that, you introduce so many failure point that it's practically impossible to get a competitive result.

Reminded of reading of specific ways you had to write bswap in C/C++ for GCC to recognize it and reduce it to a single instruction without getting into ASM, while still working with architectures that didn't have that specific instruction.

>

There is no correctness vs speed here, both code are correct. One is going to be significantly faster, but, in addition, one is going to optimize better with it surroundings, so what you'll see in practice is an even wider gap that what is presented above.

Still that example does suggest I'd get a bit of a boost by manually writing the 128bit multiply manually which would cut out overhead and a loop that's unneeded. Probably get similar results with a divide (with long or smaller divisor). Course those are rather case specific.

I wouldn't look forward to re-writing the same code for all the different compilers back ends though.

March 29, 2022
On Tuesday, 29 March 2022 at 15:23:45 UTC, H. S. Teoh wrote:
> On Tue, Mar 29, 2022 at 01:58:46PM +0000, 12345swordy via Digitalmars-d wrote:
>> On Tuesday, 29 March 2022 at 12:13:31 UTC, Adam D Ruppe wrote:
> [...]
>> > Murilo might not need a big number lib at all.
>> > 
>> > For astronomy, there's a good chance floating point will do the job.
>> 
>> That not going to work if you are comparing things that are extremely big with something that is extremely small here.
> [...]
>
> I think you got that wrong, floating is precisely designed for such comparisons. You can easily compare 1e+1000 with 1e-1000 without running into problems.
>
> Where you might run into problems is if you *add* (or subtract) extremely small numbers from extremely big numbers. Or if you divide by extremely small numbers. Or in general perform operations that mix numbers of greatly unlike magnitudes.
>
>
> T

Where did you get the 1e+1000 number from? That is way bigger then the official max size of double.
https://docs.microsoft.com/en-us/dotnet/api/system.double.maxvalue?view=net-6.0

-Alex
March 29, 2022
On Tue, Mar 29, 2022 at 05:25:39PM +0000, 12345swordy via Digitalmars-d wrote:
> On Tuesday, 29 March 2022 at 15:23:45 UTC, H. S. Teoh wrote:
[...]
> > I think you got that wrong, floating is precisely designed for such comparisons. You can easily compare 1e+1000 with 1e-1000 without running into problems.
[...]
> Where did you get the 1e+1000 number from? That is way bigger then the official max size of double.
[...]

Oops, meant to write ±300, not ±1000. :-O  The ±1000 is for the binary representation, not for decimal.


T

-- 
There are three kinds of people in the world: those who can count, and those who can't.
March 30, 2022
On 3/28/2022 12:35 PM, deadalnix wrote:
> Now let's see what we can get with clang and __int128_t, same backend so the comparison is fair:
> 
> ```cpp
> __uint128_t foobar(__uint128_t a, __uint128_t b) {
>      return a * b;
> }
> ```
> 
> codegen:
> ```asm
> foobar(unsigned __int128, unsigned __int128):        # @foobar(unsigned __int128, unsigned __int128)
>          mov     r8, rdx
>          mov     rax, rdx
>          mul     rdi
>          imul    rsi, r8
>          add     rdx, rsi
>          imul    rcx, rdi
>          add     rdx, rcx
>          ret
> ```
> 
> Why do I even have to argue that case?

You see a similar thing when 32 bit compilation does 64 bit arithmetic:

ulong foobar(ulong x, ulong y)
{
    return x * y;
}

dmd -c test.d -vasm -m32 -O
_D4test6foobarFmmZm:
0000:   53                       push      EBX
0001:   8B 54 24 14              mov       EDX,014h[ESP]
0005:   8B 44 24 10              mov       EAX,010h[ESP]
0009:   8B 4C 24 0C              mov       ECX,0Ch[ESP]
000d:   8B 5C 24 08              mov       EBX,8[ESP]
0011:   0F AF C8                 imul      ECX,EAX
0014:   0F AF D3                 imul      EDX,EBX
0017:   03 CA                    add       ECX,EDX
0019:   F7 E3                    mul       EBX
001b:   03 D1                    add       EDX,ECX
001d:   5B                       pop       EBX
001e:   C2 10 00                 ret       010h

So, yeah, supporting 128 bit arithmetic in the codegen has significant advantages. 3 multiplies and 2 adds.

Having the compiler recognize the `mul` function as a builtin would enable this code gen for 128 bits.
March 30, 2022
On 3/29/2022 9:36 AM, Era Scarecrow wrote:
>   I wouldn't look forward to re-writing the same code for all the different compilers back ends though.

That's the attractiveness of a builtin function. It'll at least work for other systems.
March 31, 2022
On Monday, 28 March 2022 at 19:35:10 UTC, deadalnix wrote:
>
> Why do I even have to argue that case?

Indeed. Bump. People please re-read deadalnix messages.

-Johan

March 31, 2022
On Thursday, 31 March 2022 at 06:31:32 UTC, Walter Bright wrote:
> You see a similar thing when 32 bit compilation does 64 bit arithmetic:
>
> [...]
>
> So, yeah, supporting 128 bit arithmetic in the codegen has significant advantages. 3 multiplies and 2 adds.
>
> Having the compiler recognize the `mul` function as a builtin would enable this code gen for 128 bits.

So now that you just killed the library solution by having the compiler specially recognize it, can we have cent/ucent?

Honestly, I don't care if DMD forward the operation to something in druntime, that would at least allow me to have good codegen on LDC/GDC.
March 31, 2022
On 31.03.22 18:32, Johan wrote:
> On Monday, 28 March 2022 at 19:35:10 UTC, deadalnix wrote:
>>
>> Why do I even have to argue that case?
> 
> Indeed. Bump. People please re-read deadalnix messages.
> 
> -Johan
> 

Well, I was with deadalnix on this even before reading the messages once. Add cent/ucent as built-in integral types. I was always under the impression that that the plan was to do it eventually.

I guess there are some inconvenient features to add to the frontend code, e.g. VRP, where a "library" solution would have an obvious excuse to just not support them.

If adding cent/ucent to the DMD backend is not an option, it can just forward to the druntime type, but other backends should be free to leverage their existing implementation. All of this is completely independent of whether or not cent/ucent are built-ins in the frontend anyway.

BTW: It's perfectly fine to just add cent/ucent built-in implementation to the vision document and maybe provide a small spec of it, then someone who needs it can implement it.