Kod, który znalazłeś, próbuje wyjaśnić, jak bardzo prymitywny sprzęt komputerowy może implementować instrukcję „dodaj”. Mówię „może”, ponieważ mogę zagwarantować, że ta metoda nie jest używana przez żaden procesor i wyjaśnię dlaczego.
W normalnym życiu używasz liczb dziesiętnych i nauczyłeś się je dodawać: Aby dodać dwie liczby, dodaj dwie najniższe cyfry. Jeśli wynik jest mniejszy niż 10, należy zapisać wynik i przejść do następnej pozycji cyfry. Jeśli wynik to 10 lub więcej, zapisz wynik minus 10, przejdź do następnej cyfry, kup pamiętaj, aby dodać jeszcze 1. Na przykład: 23 + 37, dodajesz 3 + 7 = 10, zapisujesz 0 i pamiętaj, aby dodać jeszcze 1 na następną pozycję. W pozycji 10s dodajesz (2 + 3) + 1 = 6 i zapisujesz. Wynik to 60.
Możesz zrobić dokładnie to samo z liczbami binarnymi. Różnica polega na tym, że jedynymi cyframi są 0 i 1, więc jedynymi możliwymi sumami są 0, 1, 2. W przypadku liczby 32-bitowej należy obsłużyć jedną pozycję cyfry po drugiej. I tak zrobiłby to naprawdę prymitywny sprzęt komputerowy.
Ten kod działa inaczej. Wiesz, że suma dwóch cyfr binarnych wynosi 2, jeśli obie cyfry są równe 1. Więc jeśli obie cyfry mają wartość 1, to dodasz jeszcze 1 na następnej pozycji binarnej i zapiszesz 0. To właśnie robi obliczenie t: Znajduje wszystkie miejsca gdzie obie cyfry binarne to 1 (to jest &) i przenosi je do następnej pozycji cyfry (<< 1). Następnie dodaje: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 równa się 2, ale zapisujemy 0. To właśnie robi wyłącznik lub operator.
Ale wszystkie jedynki, które musiałeś obsłużyć na następnej pozycji cyfry, nie zostały obsłużone. Nadal trzeba je dodać. Dlatego kod wykonuje pętlę: w następnej iteracji dodawane są wszystkie dodatkowe jedynki.
Dlaczego żaden procesor nie robi tego w ten sposób? Ponieważ jest to pętla, a procesory nie lubią pętli i jest powolna. Jest powolny, ponieważ w najgorszym przypadku potrzebne są 32 iteracje: Jeśli dodasz 1 do liczby 0xffffffff (32 1-bity), to pierwsza iteracja czyści bit 0 y i ustawia x na 2. Druga iteracja czyści bit 1 y i ustawia x na 4. I tak dalej. Uzyskanie wyniku zajmuje 32 iteracje. Jednak każda iteracja musi przetworzyć wszystkie bity x i y, co wymaga dużej ilości sprzętu.
Prymitywny procesor robiłby rzeczy tak samo szybko, jak arytmetyka dziesiętna, od najniższej do najwyższej pozycji. Wykonuje również 32 kroki, ale każdy krok przetwarza tylko dwa bity plus jedną wartość z poprzedniej pozycji bitu, więc jest znacznie łatwiejszy do wdrożenia. Nawet w prymitywnym komputerze można sobie na to pozwolić bez konieczności implementowania pętli.
Nowoczesny, szybki i złożony procesor będzie używał „sumatora warunkowego”. Zwłaszcza jeśli liczba bitów jest duża, na przykład sumator 64-bitowy, oszczędza dużo czasu.
Sumator 64-bitowy składa się z dwóch części: Po pierwsze, sumator 32-bitowy dla najniższego 32-bitowego. Ten 32-bitowy sumator wytwarza sumę i „przeniesienie” (wskaźnik, że 1 musi zostać dodana do następnej pozycji bitowej). Po drugie, dwa 32-bitowe sumatory dla wyższych 32 bitów: jeden dodaje x + y, a drugi x + y + 1. Wszystkie trzy sumatory działają równolegle. Następnie, gdy pierwszy sumator wygeneruje przeniesienie, procesor po prostu wybiera, który z dwóch wyników x + y lub x + y + 1 jest prawidłowy i otrzymujesz pełny wynik. Tak więc 64-bitowy dodatek zajmuje tylko odrobinę więcej czasu niż 32-bitowy, a nie dwa razy dłużej.
32-bitowe sumatory są ponownie implementowane jako sumatory sum warunkowych, przy użyciu wielu sumatorów 16-bitowych, a sumatory 16-bitowe są sumatorami sum warunkowych i tak dalej.
add
Wydaje mi się, że większość implementacji będzie używać natywnych instrukcji maszynowych, które, jak sądzę, mają prawie wszystkie procesory i zaimplementowane jako sumatory sprzętowe, które działają w kilku zegarach.