Pisałem asynchroniczny framework rejestrowania, w którym miałem wiele wątków wysypujących dane. Zacząłem grać w Boost asio, ponieważ oferował kilka prostych sposobów na wymuszanie serializacji i zamawiania. Ponieważ jestem początkującym, zacząłem mój projekt z bezpiecznym wątku (używany boost::mutex
i) circular bounded_buffer (który był w rzeczywistości wektor).Zwiększenie wdrożenia ASIO IO_SERVICE?
Napisałem mały prosty test porównawczy do pomiaru wydajności. Benchmark to tylko jeden wątek rejestrujący milion wiadomości (przesuwając go do bufora), a mój wątek roboczy pobierałby wiadomości z kolejki, aby logować się do pliku/konsoli/listy rejestratorów. (P.S. Używanie muteksa i C.V było poprawne, a wskaźniki do wiadomości były przenoszone, więc z tego punktu widzenia wszystko było w porządku/wydajne).
Kiedy zmieniłem realizację zamiast korzystania boost::asio::io_service
i i mających pojedynczy wątek wykonujący run()
wydajność naprawdę poprawie (w rzeczywistości jest skalowany naprawdę dobrze na zwiększenie liczby wiadomości są rejestrowane w przeciwieństwie do wydajności poniżające w moim początkowym prostego modelu)
Oto kilka pytań, które chcę wyjaśnić.
Dlaczego poprawa wydajności? (Myślałem, że implementacja wewnętrzna ma wątkową bezpieczną kolejkę dla procedur obsługi, co czyni ją bardziej wydajną niż mój własny początkowy prosty wątek bezpieczny projekt kolejki). Proszę wziąć pod uwagę, że mój projekt został dobrze oceniony i nie miał żadnych wad jako takich (kod szkieletu był oparty na sprawdzonych przykładach), czy ktoś mógłby rzucić więcej światła na wewnętrzne szczegóły tego, jak implementuje to
io_service
.Drugą interesującą obserwacją było to, że przy zwiększaniu ilości wątków moja początkowa wydajność implementacji poprawiła się, ale kosztem utraty serializacji/porządku, ale wydajność uległa pogorszeniu (bardzo nieznacznie) dzięki boost :: asio (myślę, że to dlatego, że moje programy obsługi wykonywali bardzo uproszczone zadanie, a przełączanie kontekstu było poniżające, spróbuję wykonać bardziej złożone zadanie i opublikuję swoje obserwacje później).
Naprawdę chciałbym wiedzieć, czy
boost::asio
jest właśnie przeznaczona dla operacji I/O i sieciowych lub jest mój zwyczaj używania go za to zadanie współbieżne (równoległe) przez puli wątków jest dobre podejście do projektowania. Czy obiekt jest przeznaczony wyłącznie do obiektów i/o (jak napisano w dokumentacji), ale okazało się, że jest to naprawdę ciekawy sposób pomagania mi w rozwiązywaniu równoległych zadań (nie tylko i/o lub związanych z siecią) w serializowany sposób (czasami wymuszając zamawianie za pomocą pasm). Jestem nowy, aby wzmocnić i naprawdę ciekawi, dlaczego podstawowy model nie działał/skalował się, jak również kiedy użyłem boost asio.
Wyniki: (zarówno po prostu miał 1 wątku roboczego)
- 1000 zadanie: 10 mikro s/zadania w obu przypadkach
- 10000 zadanie: 80 mikro s (ograniczony bufor), 10 mikro sw impuls asio
- 100000 zadanie 250 mikro s (bufor bounde), 10 s w mikro impuls asio
byłoby interesujące k teraz jak boost rozwiązuje problem bezpieczny dla wątków w io_service
kolejce bezpiecznej dla wątków dla handlerów (zawsze myślałem, że na pewnym poziomie implementacji muszą również używać blokad i c.v).
Użyłem 'boost :: asio' do zarządzania innymi typami zadań asynchronicznych (nie tylko siecią IO), aby osiągnąć sukces. – Chad
Wiem, że jest to stare pytanie, ale może się zdarzyć, że (w systemie Windows) ASIO używa portów zakończenia IO, co może skutkować mniejszą liczbą wywołań systemowych. – Pete