Szukam kodu C dla podpisanego nasyconego 64-bitowego dodatku, który kompiluje się do wydajnego kodu X86-64 z optymalizatorem gcc. Kod przenośny byłby idealny, chociaż w razie potrzeby można by zastosować rozwiązanie asm.Podpisano nasycony dodatek 64-bitowy ints?
static const int64 kint64max = 0x7fffffffffffffffll;
static const int64 kint64min = 0x8000000000000000ll;
int64 signed_saturated_add(int64 x, int64 y) {
bool x_is_negative = (x & kint64min) != 0;
bool y_is_negative = (y & kint64min) != 0;
int64 sum = x+y;
bool sum_is_negative = (sum & kint64min) != 0;
if (x_is_negative != y_is_negative) return sum; // can't overflow
if (x_is_negative && !sum_is_negative) return kint64min;
if (!x_is_negative && sum_is_negative) return kint64max;
return sum;
}
Funkcja w formie pisemnej wytwarza dość długie wyjście zespołu z kilkoma odgałęzieniami. Wszelkie wskazówki dotyczące optymalizacji? Wygląda na to, że powinno być możliwe do wdrożenia za pomocą tylko ADD z kilkoma instrukcjami CMOV, ale jestem trochę zardzewiały z tego typu rzeczy.
Twój sposób obliczania znaku twoich wartości jest zbyt skomplikowany, dlaczego nie użyć po prostu '(x <0)' np.? Aby być przenośnym użyj '[u] int64_t'. Wtedy masz 'INT64_MAX' i' INT64_MIN' za darmo i nie musisz używać do tego własnych stałych. –
możliwy duplikat [Bitwise nasycony dodatek w C (HW)] (http://stackoverflow.com/questions/5277623/bitwise-saturated-addition-in-c-hw) – jxh
gcc może zoptymalizować operacje na 128-bitowych liczbach. Spróbuj czegoś, co działa jak 'clamp ((int128_t) x + y, INT64_MIN, INT64_MAX))' i sprawdź, czy jest to dopuszczalne. – zch