Trochę montażu

29 sierpnia 2009 przez Prashant · Komentarze
Opublikowane jako: technologii

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

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