[C WinAPI] Wydajność standardowych semaforów binarnych w win

0

Witam,

Tak sobie sprawdziłem wydajność standardowych semaforów binarnych w windows... i trochę się zaskoczyłem:

  ...
  for (int i = 0; i < NR_ITER; ) {
    WaitForSingleObject(mutex, INFINITE);
    i++;
    ReleaseMutex(mutex);
  }
  ...

Pętla bardzo prosta, tylko jeden wątek więc nie wystąpi nigdy blokowanie (chciałem tylko sprawdzić wydajność opuszczania i podnoszenia semafora). I oto jakie wyniki uzyskałem:

E:\projects\MutexTest>g++ MutexTest.cpp -o MutexTest.exe -O3 && MutexTest.exe
1000000 iter / 1.029 sec = 971817.298 iter/sec = 1029.000 nanosec/iter

Ponad 1 mikrosekunda na jeden obieg pętli... Cała wieczność :) Wcześniej wydawało mi się, że w środku kryje się pare instrukcji asemblerowych (w stylu XCHG) tak, że całość wykona się bardzo szybko, ale jest inaczej. Pewnie dlatego, że z tych semaforów korzysta się przy używaniu wolniejszych podzespołów systemu operacyjnego (np pliki, zasoby sieciowe), a nie są one przydatne przy tworzeniu wydajnego oprogramowania korzystającego z wielowątkowości.

Zna ktoś może jakieś szybsze funkcje/biblioteki do obsługi semaforów?

0

Eeee bez sensu. Testowałeś przez jedną sekundę, to za mało. Zastanawiam się jakie byś wyniki dostał zostawiając samą pętlę ;) Aplikacja najbardziej się mozoli na początku zaraz po uruchomieniu, zanim manager procesów się skapuje, że potrzeba więcej czasu procka dla niej.

Poza tym jeśli aplikacja ma być superwydajne to się raczej staraj pozbyć wielowątkowości a przynajmniej częstej synchronizacji, a nie biadol że za długo ;) . Albo chwyć się za assemblera :)
Ciekawe ile w twojej aplikacji zajęłaby sama synchronizacja ? No bo jeśli nie więcej jak 2, 3 % to raczej gdzie indziej trzeba szukać przyspieszenia.

0

a nie są one przydatne przy tworzeniu wydajnego oprogramowania korzystającego z wielowątkowości.

Sam MS w dokumentacji pisał, że do lokalnej synchronizacji lepiej używać sekcji krytycznych jeżeli zależy nam na szybkości działania.

0
adf88 napisał(a)

Eeee bez sensu. Testowałeś przez jedną sekundę, to za mało. Zastanawiam się jakie byś wyniki dostał zostawiając samą pętlę ;) Aplikacja najbardziej się mozoli na początku zaraz po uruchomieniu, zanim manager procesów się skapuje, że potrzeba więcej czasu procka dla niej.

Hmm jedna sekunda to już dość dużo. Przeprowadziłem testy dla 10 sekund i wychodzi prawie to samo.

0x666 napisał(a)

a nie są one przydatne przy tworzeniu wydajnego oprogramowania korzystającego z wielowątkowości.

Sam MS w dokumentacji pisał, że do lokalnej synchronizacji lepiej używać sekcji krytycznych jeżeli zależy nam na szybkości działania.

O to już jest lepsze. Średni czas wejścia do sekcji + wyjścia z sekcji (przy założeniu że nie wystąpi blokowanie) to 55 nanosekund. Do większości przypadków pewnie to wystarczy.

Podsumowując:

SEMAFOR BINARNY -> 10000000 ITER / 9.688 sec = 1032204.789 ITER/sec = 968.800 nanosec/ITER
SEKCJA KRYTYCZNA -> 200000000 ITER / 11.060 sec = 18083182.640 ITER/sec = 55.300 nanosec/ITER

0

Jeszcze masz funkcje z rodziny Interlockedxxx (np. InterlockedExchange, InterlockedCompareExchange itd.).

1 użytkowników online, w tym zalogowanych: 0, gości: 1