Trochu montáže

29.srpna 2009 od Prashant · Komentáře
Soubor pod: technologie

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

 # Include 
 int 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;
 }