Trochę montażu
Po przeczytaniu tego artykułu o Lock Free buforów i widząc wykorzystanie CAS (porównania i wymiany), czułem się jak zamieszczenie kodu assemblera zrobić to samo. Użyj przypadek tam było napisanie natywnej metody i wywołać ją z powrotem w Java (1.5, kiedy równoległe struktury danych w Javie były mniej lub bardziej nie istnieje). Bez zbędnych ceregieli, będę uwolnić kod na Ciebie
. Pierwszy z nich to CAS i drugie jest dla komputerów GCD za pomocą algorytmu Euklidesa (ten można znaleźć w wielu miejscach i tutoriali jak również).
Skompilować i uruchomić instrukcje gcc file_name.c ; ./a.out
Porównaj i Zamień
# Include# Include / / Wymiany - nowa_wartość, comperand jest stary / wartość oczekiwana / * * Funkcja faktycznie robi następującą rzecz - jeżeli wartość do * dest jest równa OldValue następnie zastąpić ją nowa_wartość jeszcze pozostawić bez zmian: czy wszystkie te atomowo * * Istnieją dwie opcje do wartości zwracanej * 1.is wartość początkowa od * dest i pozostawić ciężar fxn wywołującego ją porównać z oldval * 2. zrobić to tu i zwraca 0 lub 1, powinno to być bardziej efektywne ** / / * Później zmienić go na makro * / int CAS (int * dest, int OldValue, int nowa_wartość) { printf ("(% d,% d,% d)", * dest, OldValue, nowa_wartość); / * Int cas (int dest, int OldValue, int nowa_wartość) {* / / * Int cas (int dest, int nowa_wartość, int OldValue) {* / int wynik = 1 ;/ * 1 pokazuje, że cas udało i 0 pokazuje, że nie udało * / / * Btw trzeba ustawić CC flaga przebijania! * / volatile__ __ __asm__ ( "Movl% 2,%% eax \ n \ t" "Movl% 3,%% ebx \ n \ t" "Movl 0%%% ecx \ n \ t" "LOCK \ n \ t" "CmpXchg ebx%%%% (ECX) \ n \ t" / * powinno LOCK być na tej samej linii * / "Jz SPORZĄDZONO \ n \ t" "Movl 0 dolarów,% 1 \ n \ t" "DONE: \ n \ t" : "= M" (przeznaczenie), "= g" (wynik) : "G" (OldValue), "g" (nowa_wartość), "m" (docelowy) : "% Eax", "% ebx", "ecx", "cc" ); printf ("(% d,% d,% d)", * dest, OldValue, nowa_wartość); return wynik; } / * TODO * Napisać kolejną asm fxn który stawia przede fxn w pętli i próbować, chyba że uda * / int main () { int a = 5, b = 6; int * c = (int *) malloc (sizeof (int)); * C = 6; / * Int c = 6, * / printf ("% d \ n", cas (c, b, b)); printf ("% d \ n", cas (c, b,)); printf ("% d \ n", cas (c,,)); printf ("% d \ n", cas (c, b, b)); * C = 6; / * C = 5, * / printf ("zmienia wartość * c% d \ n", * c); printf ("% d \ n", cas (c, b, b)); printf ("% d \ n", cas (c, b,)); printf ("% d \ n", cas (c,,)); printf ("% d \ n", cas (c, a, b)); printf ("% d \ n", cas (c, b,)); return 0; }
Formatowanie zauważa - Wygląda wyróżnienia składni wp jest dodanie w końcu zignorować.
GCD
# Includeint nwd (int a, int b) { int wynik; / * Oblicz Największy wspólny dzielnik za pomocą algorytmu Euklidesa * / volatile__ __ __asm__ ("movl% 1,%% eax;" "Movl% 2,%% ebx;" "Cd: cmpl 0 dolarów,%% ebx;" "Je zrobić;" "Xorl%% edx,%% edx;" "Idivl%% ebx;" "Movl%% ebx,%% eax;" "Movl%% edx, ebx%%;" "Jmp cd.;" "DONE: movl%% eax,% 0,": "= g" (wynik): "g" (), "g" (b) ); return wynik; } int main () { int pierwszy, drugi; printf ("Podaj dwie liczby całkowite:"); scanf ("% d% d", & najpierw & sekund); printf ("NWD z% d &% d jest% d \ n", pierwszy, drugi, NWD (pierwsza, druga)); return 0; }



































