Dlaczego pobieranie wielu wątków jest szybsze niż pojedynczy wątek?

13

Na moim serwerze jest jeden duży plik. Uważam, że pobieranie wielu wątków może uzyskać 20 Mb / s, ale pojedynczy wątek może uzyskać 10 Mb / s, czy ktoś może to wyjaśnić?

dlaczego
źródło
Wiele wątków obsługujących to samo połączenie TCP, czy wiele wątków z osobnymi połączeniami TCP? Czy mówisz także, że serwer jest wielowątkowy, czy klient jest wielowątkowy, czy jedno i drugie?
Spiff

Odpowiedzi:

14

Zwykle dzieje się tak, ponieważ gdzieś między tobą a drugim serwerem znajduje się zapora ogniowa ograniczająca każdy strumień HTTP do 10 Mb / s. Korzystając z wielu wątków, otrzymujesz 2x 10 Mb (jeden dla każdego wątku).

Mark Henderson
źródło
1
Korzystam z FTP i nie ma żadnych ograniczeń na moim serwerze
dlaczego
@ dlaczego: może to twój dostawca Internetu ogranicza każde połączenie do prędkości 10 Mb / s? Czy możesz uzyskać więcej niż w testerze prędkości?
André Paramés
4

Wynika to z twojego pingowania pomiędzy tobą a serwerem i rozmiaru pakietu / rozmiaru okna tcpip używanego przez twoje oprogramowanie do pobierania.

Zasadniczo, jeśli masz ping 100ms na serwer i żądasz pakietów 100kb, możesz uzyskać tylko 10 pakietów na sekundę za pomocą 1 połączenia, nawet jeśli Twoja prędkość Internetu jest nieskończona.

BarsMonster
źródło
Nie musisz potwierdzać każdego pakietu, dopóki odbiornik opróżnia bufor w rozsądnym tempie, nadawca powinien mieć możliwość ciągłego pompowania.
André Paramés
Zgadza się. Ale nawet przy buforze 256 kb ping nadal powoduje ogromne spowolnienie
BarsMonster
3

TCP działa najlepiej, gdy „utrzymujesz potok pełny” - gdy aplikacja wysyłająca wysyła bufory wystarczająco szybko, aby nadawca stos TCP był stale dostarczany z danymi, dzięki czemu zawsze może mieć dane „w locie” w sieci, a kiedy odbiornik aplikacja odczytuje stos TCP odbiornika wystarczająco szybko, aby okno TCP odbiornika nigdy się nie zapełniło (ponownie, więc wysyłający stos TCP zawsze może utrzymywać dane „w locie” w sieci).

Mogę sobie wyobrazić źle napisaną aplikację jednowątkowego nadawcy, która przekazuje jeden bufor do stosu TCP, czeka, aby usłyszeć, że została w pełni potwierdzona, a następnie przekazuje inny bufor. Oznacza to, że gdy koniec pierwszego bufora będzie „w locie” w sieci, stos TCP wysyłającego jest głodny, aby dane mogły zostać wysłane, co oznacza, że ​​rura opróżnia się i nie jest uzupełniana, dopóki nie wróci Ack i aplikacja wysyłająca przekazuje mu nowy bufor.

Mogę również wyobrazić sobie źle napisaną aplikację jednowątkowego odbiornika, która nie odczytuje wystarczająco szybko ze stosu odbierającego TCP, a tym samym pozwala zapełnić bufory stosu TCP, co oznacza, że ​​okno TCP zapełnia się, co powoduje, że stos TCP wysyła przestań wysyłać, dopóki okno się nie otworzy. Zwiększenie rozmiaru okna TCP odbiornika może trochę pomóc, ale prawdziwym rozwiązaniem w tym zakresie jest szybszy odczyt danych.

Spiff
źródło
Więc może to nie mieć nic wspólnego z byciem jednowątkowym?
Ape-inago,
@ Ape-inago Pewnie, dobrze napisana aplikacja jednowątkowa mogłaby utrzymać rurkę pełną, tak.
Spiff
2

Prawdopodobnie dlatego, że możesz przesłać tyle danych tylko przez jedno połączenie. Jednak w programie wielowątkowym możesz mieć dwa połączenia odbierające dane w tym samym czasie i podwajające ilość informacji, które możesz uzyskać. Istnieją pewne ograniczenia, na przykład prędkość serwera, z którego pobierasz ... Czapki z głów przed dwoma, którzy napisali wielowątkowy downloader, nie są łatwe do napisania.

Joshkunz
źródło
1
Dlaczego to takie trudne? Musisz tylko przydzielić osobną sekcję dla każdego wątku i pozwolić, aby zapisał się w odpowiedniej sekcji pliku wynikowego. Źródło axela wydaje mi się dość proste.
André Paramés