🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

4 total messages Started by Borneq Tue, 05 Nov 2019 11:30
Mnożenie i dodawanie 64 bitowych liczb
#309964
Author: Borneq
Date: Tue, 05 Nov 2019 11:30
23 lines
1856 bytes
Mam x*y+a+b
Mnożenie używa intrin.h lub GCC 128 bitów według 
https://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication

Teraz mam jeszcze dodanie dwóch liczb 64 bitowych do 128 bitowego 
rezultatu złożonego z dwóch zmiennych
przy dodawaniu albo nie nastąpi przepełnienie albo gdy nastąpi to 
starszy wyraz zwiększamy o 1,
można zrobić jakąś detekcję, gdy po dodaniu wynik jest mniejszy niż 
każdy ze składników, wystarczy chyba porównać z jednym dowolnym, to 
zwiększamy o 1, nie trzeba by nawet działać na 128 bitach, ale...
musiałbym użyć if, które chyba od Pentium jest wolne, bo niszczy 
potokowość instrukcji.
I czy lepiej
128+64
128+64

czy najpierw zsumować dwa mniejsze:
64+64 = 64 + carry
128+64+carry

Wolałbym nie robić wstawek w assemblerze, przy mnożeniu się udało, gdy 
korzystam z intrin.h , ale została jeszcze drobnostka dwóch dodawań.
Re: Mnożenie i dodawanie 64 bitowych liczb
#309965
Author: Wojciech Muła
Date: Tue, 05 Nov 2019 12:02
44 lines
3073 bytes
On Tuesday, November 5, 2019 at 12:31:33 PM UTC+1, Borneq wrote:
> Mam x*y+a+b
> Mnożenie używa intrin.h lub GCC 128 bitów według 
> https://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
> 
> Teraz mam jeszcze dodanie dwóch liczb 64 bitowych do 128 bitowego 
> rezultatu złożonego z dwóch zmiennych
> przy dodawaniu albo nie nastąpi przepełnienie albo gdy nastąpi to 
> starszy wyraz zwiększamy o 1,
> można zrobić jakąś detekcję, gdy po dodaniu wynik jest mniejszy niż 
> każdy ze składników, wystarczy chyba porównać z jednym dowolnym, to 
> zwiększamy o 1, nie trzeba by nawet działać na 128 bitach, ale...
> musiałbym użyć if, które chyba od Pentium jest wolne, bo niszczy 
> potokowość instrukcji.
> I czy lepiej
> 128+64
> 128+64
> 
> czy najpierw zsumować dwa mniejsze:
> 64+64 = 64 + carry
> 128+64+carry
> 
> Wolałbym nie robić wstawek w assemblerze, przy mnożeniu się udało, gdy 
> korzystam z intrin.h , ale została jeszcze drobnostka dwóch dodawań.

Zamiast gdybać o przedpotopowych Pentiumach warto sprawdzić, co robi
kompilator.

#include <cstdint>

void add(uint64_t a, uint64_t b, uint64_t& lo, uint64_t& hi)
{
    hi += uint64_t(__builtin_uaddl_overflow(a, b, &lo));
}

Powyższy kod jest kompilowany przez GCC i clanga do:

  add rdi, rsi
  mov QWORD PTR [rdx], rdi
  adc QWORD PTR [rcx], 0

Kompilator intela generuje dłuższy kod, ale też bez skoków.

w.
Re: Mnożenie i dodawanie 64 bitowych liczb
#309966
Author: Borneq
Date: Tue, 05 Nov 2019 12:58
13 lines
1573 bytes
W dniu 05.11.2019 o 13:02, Wojciech Muła pisze:
> void add(uint64_t a, uint64_t b, uint64_t& lo, uint64_t& hi)
> {
>      hi += uint64_t(__builtin_uaddl_overflow(a, b, &lo));
> }

Fajna funkcja __builtin_uaddll_overflow (dodałem jeszcze drugie l w 
nazwie bo tak działała na 32 bitach w Clion (mingw) pod Windows)
Ale..nie widzę jak można dodać taką funkcję w Visual C++

widzę ze jest coś takiego jak
__MACHINEX64(unsigned char __cdecl _addcarry_u64(unsigned char, unsigned 
__int64, unsigned __int64, unsigned __int64 *))
Re: Mnożenie i dodawanie 64 bitowych liczb
#309967
Author: Borneq
Date: Tue, 05 Nov 2019 14:54
19 lines
1856 bytes
W dniu 05.11.2019 o 13:58, Borneq pisze:
> W dniu 05.11.2019 o 13:02, Wojciech Muła pisze:
>> void add(uint64_t a, uint64_t b, uint64_t& lo, uint64_t& hi)
>> {
>>      hi += uint64_t(__builtin_uaddl_overflow(a, b, &lo));
>> }
> 
> Fajna funkcja __builtin_uaddll_overflow (dodałem jeszcze drugie l w 
> nazwie bo tak działała na 32 bitach w Clion (mingw) pod Windows)
> Ale..nie widzę jak można dodać taką funkcję w Visual C++
> 
> widzę ze jest coś takiego jak
> __MACHINEX64(unsigned char __cdecl _addcarry_u64(unsigned char, unsigned 
> __int64, unsigned __int64, unsigned __int64 *))

I sztuczka bazująca na żródłach MPIR, czyli porównuję, ale nie skaczę:
lo = a + b;
hi += lo < a;
ewentualnie tuning prędkosci dla lo < b, bo od obu ma byc mniejsze
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads