Trochu montáže
Po přečtení tohoto článku o nárazníky Lock Free a viděl využití CAS (srovnání a výměna), připadal jsem si jako vysílání kód assembleru, aby učinily totéž. Use case tam bylo napsat nativní metody a volat z Java zpět do 1.5, kdy souběžné datové struktury v Javě byly více či méně neexistuje). Bez dalších okolků, já se uvolnil kód na vás
. Prvním z nich je pro CAS a druhý je pro výpočetní GCD pomocí Euclida algoritmus (ten lze nalézt na mnoha místech a cvičení i).
Kompilovat a spouštět instrukce gcc file_name.c ; ./a.out
Porovnejte a Swap
# Include# Include / / Výměna - newValue, comperand je starý / očekávaná hodnota / * * Funkce vlastně dělá následující věc - pokud je hodnota na * dest se rovná oldvalue pak jej nahradit jiným newValue ponechat beze změny: to vše atomicky * * Existují dvě možnosti pro návratové hodnoty * 1.is počáteční hodnota z * dest a nechat zátěže volajícího fxn porovnat ji s oldval * 2. to sem a vrátí 0 nebo 1, mělo by to být efektivnější ** / / * Později změnit v makru * / int cas (int * dest, int oldvalue, int newValue) { printf ("(% d,% d,% d)", * dest, oldvalue, newValue); / * Int CAS (int dest, int oldvalue, int newValue) {* / / * Int CAS (int dest, int newValue, int oldvalue) {* / int result = 1 ;/ * 1 ukazuje, že se podařilo cas a 0 ukazuje, že se nezdařilo * / / * Btw třeba nastavit cc pro vlajky přepisování! * / __asm__ __ volatile__ ( "Movl% 2,%% eax \ n \ t" "Movl% 3,%% ebx \ n \ t" "Movl% 0,%% ecx \ n \ t" "LOCK \ n \ t" "CMPXCHG%% ebx, (%% ecx) \ n \ t" / * LOCK by měl být na stejném řádku * / "JZ Dáno \ n \ t" "Movl $ 0,% 1 \ n \ t" "Dáno: \ n \ t" : "= M" (dest), "= g" (výsledek) : "G" (oldvalue), "G" (newValue), "m" (dest) : "% Eax", "% ebx", "ecx", "cc" ); printf ("(% d,% d,% d)", * dest, oldvalue, newValue); return vysledek; } / * TODO * Napsat další asm fxn který se projevuje především fxn v cyklu while a dál snažit, pokud uspěje * / int main () { int = 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 ("měnící se hodnota * c k% 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; }
Formátování poznámky - se zdá být jako zvýrazňovač syntaxe wp je přidání nakonec ignorovat.
GCD
# Includeint gcd (int, int b) { int vysledek; / * Počítat největší společný dělitel pomocí Euclida algoritmus * / __asm__ __ volatile__ ("movl% 1,%% eax;" "Movl% 2,%% ebx;" "CONTD: cMpl $ 0,%% ebx;" "Je provedeno;" "Xorl%% edx,%% edx;" "Idivl%% ebx;" "Movl%% ebx,%% eax;" "Movl%% edx,%% ebx;" "Jmp CONTD;" "Dáno: movl%% eax,% 0;": "= g" (výsledek): "g" (), "G" (b) ); return vysledek; } int main () { int první, druhý, printf ("Zadejte dvě celá čísla:"); scanf ("% d% d", a první, a druhý); printf ("% d GCD ze &% d je% d \ n", první, druhá, gcd (první, druhá)); return 0; }



































