Thread View: pl.comp.lang.c
4 messages
4 total messages
Started by Borneq
Tue, 05 Nov 2019 11:30
Mnożenie i dodawanie 64 bitowych liczb
Author: Borneq
Date: Tue, 05 Nov 2019 11:30
Date: Tue, 05 Nov 2019 11:30
23 lines
1856 bytes
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
Author: Wojciech Muła
Date: Tue, 05 Nov 2019 12:02
Date: Tue, 05 Nov 2019 12:02
44 lines
3073 bytes
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
Author: Borneq
Date: Tue, 05 Nov 2019 12:58
Date: Tue, 05 Nov 2019 12:58
13 lines
1573 bytes
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
Author: Borneq
Date: Tue, 05 Nov 2019 14:54
Date: Tue, 05 Nov 2019 14:54
19 lines
1856 bytes
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