2012-10-13 11 views
6

Zazwyczaj bignum są realizowane za pomocą wielu słów, ale chciałbym wybrać rozmiar słowa tak przenośnie, jak to możliwe. Jest to trudniejsze, niż mogłoby się wydawać - std::uint64_t jest dostępne w wielu kompilatorach 32-bitowych, ale prawdopodobnie lepszym wyborem byłby 32-bitowy komputer. Tak więc pokusą byłoby użycie std :: size_t, ale nie ma gwarancji dla danej architektury, że std::size_t jest najbardziej wydajnym typem dla arytmetyki, na przykład na the new x32 Linux ABIstd::size_t będzie 32-bitowy, ale std::uint64_t nadal będzie najlepszym wyborem.Określanie najbardziej efektywnego rozmiaru słowa do implementacji binarnych w C++ 11?

C++ 11 ma zdefiniowane szybkie/najmniej różne typy różnych rozmiarów, ale nie daje żadnego sposobu na zapytanie o ich względną wydajność. Zdaję sobie sprawę, że może nie być najlepszej przenośnej odpowiedzi, teraz domyślam się, że domyślnie jest std::size_t i wykrywam wyjątkowe architektury w czasie konfiguracji. Ale może jest lepszy sposób?

+4

Myślę, uint_fast32_t lub uint_fast64_t może być najlepsze rozwiązanie. Zapewni to przynajmniej szybkość i co najmniej 32/64 bitów dla typów danych. Zapewne to są ich przeznaczeniem. – Morwenn

+0

"* C++ 11 upoważnia, że ​​std :: uint64_t istnieje na przykład *" Nie, nie działa. To opcjonalne. Ponadto: "* ale std :: uint32_t prawdopodobnie byłby lepszym wyborem na 64-bitowej maszynie *" Zakładam, że masz na myśli "** 32-bitowy ** komputer" –

+0

@NicolBolas: Ups, masz rację w obu przypadkach. –

Odpowiedz

5

Prawdziwym kluczem do efektywnego wdrażania jest to, że musisz powiększyć mnożenie, które daje 2x tyle bitów, co Twój podstawowy rozmiar słowa. Więc możesz używać uint64_t jako podstawowego rozmiaru słowa, jeśli twoja platforma obsługuje 128-bitowy wynik mnożenia. Rozmiar wskaźników na twoim komputerze jest w dużej mierze nieistotny.

Jeśli naprawdę chcesz, aby najskuteczniejsza implementacja była jak najbardziej przenośna, powinieneś wybrać rozmiar słowa do wybrania w czasie kompilacji. Następnie użyj skryptu autokonfiguracji, który (próbuje) zbudować kod o różnych rozmiarach słów i przetestować wyniki tych kompilacji pod kątem poprawności i szybkości.

#define WORD_(SIZE) std::uint ## SIZE ## _t 
#define WORD(SIZE)  WORD_(SIZE) 
#define X2_(SIZE)  X2_ ## SIZE 
#define X2(SIZE)  X2_(SIZE) 
#define X2_8   16 
#define X2_16   32 
#define X2_32   64 
#define X2_64   128 

użycie WORD(WORD_SIZE) i WORD(X2(WORD_SIZE)) w kodzie i skompilować z
-DWORD_SIZE=8 lub 16 lub 32 lub 64