2013-02-25 12 views
7

Zastanawiasz się, jaki jest najlepszy sposób, aby zdecydować, kiedy przerwać tworzenie nowych wątków na maszynie z pojedynczym rdzeniem, która uruchamia ten sam program wiele razy jako wątek?Optymalizacja maksymalnej liczby wątków uruchomionych na procesorze

Wątki pobierają zawartość internetową i przetwarzają, co oznacza, że ​​obciążenie każdego wątku nie jest stałe aż do zakończenia wątku.

Myślę, że mam wątek, który monitoruje obciążenie procesora/pamięci RAM i przestaje tworzyć wątki, jeśli obciążenie osiągnie określony próg, ale także przestanie tworzyć wątki po osiągnięciu określonej liczby wątków, aby upewnić się, że Procesor nie jest przeciążany.

Jakie są opinie na temat dostępnych technik, aby to osiągnąć?

Dziękujemy, Vladimir

+3

Myślę, że jesteś na dobrej drodze. Jedną z rzeczy do rozważenia jest użycie NIO i selektorów, więc twoje wątki są zawsze zajęte, a nie zawsze czekają na IO.Trudno będzie zmaksymalizować przepustowość, nie licząc szczytów i dolin. – Gray

+0

Tam, Gray pobił mnie do tego :) Z blokującym IO będziesz potrzebował śmiesznie dużej ilości wątków, które będą marnować pamięć RAM i robiąc w zasadzie tylko czekać. –

+0

Możesz nie chcieć tworzyć nici samodzielnie. Użyj 'ExecutorService', która ponownie wykorzystuje wątki dla zadań' Runnable' lub 'Callable' i redukuje narzut tworzenia niszczących wątków. –

Odpowiedz

1

To będzie trudne do zrobienia tego poprzez monitorowanie procesora używanego przez aktualnego procesu. Liczby te mają tendencję do opóźniania rzeczywistości, a ich wynikiem będą w dużej mierze szczyty i doliny. Problem polega na tym, że twoje wątki będą najczęściej blokowane przez IO i nie ma dobrego sposobu na przewidzenie, kiedy bajty będą dostępne do odczytania w najbliższej przyszłości.

Powiedziawszy, możesz zacząć od ThreadPoolExecutor przy określonym maksymalnym numerze wątku (dla pojedynczego procesora powiedzmy 4), a następnie sprawdzać co 10 sekund lub mniej więcej średnią obciążenia. Jeśli średnia obciążenia jest poniżej tego, co chcesz, możesz zadzwonić pod numer setMaximumPoolSize(...) z większą wartością, aby zwiększyć ją przez następne 10 sekund. Może zaistnieć potrzeba sondowania 30 lub więcej sekund między kolejnymi obliczeniami, aby wygładzić wydajność aplikacji.

Można użyć następującego kodu do śledzenia całkowitego czasu procesora dla wszystkich wątków. Nie wiem, czy to najlepszy sposób to zrobić

long total = 0; 
    for (long id : threadMxBean.getAllThreadIds()) { 
     long cpuTime = threadMxBean.getThreadCpuTime(id); 
     if (cpuTime > 0) { 
      total += cpuTime; 
     } 
    } 
    // since is in nano-seconds 
    long currentCpuMillis = total/1000000; 

Zamiast próbować zwiększyć poziom procesora dla pająka, możesz rozważyć próbuje zmaksymalizować przepustowość. Pobierz próbkę liczby stron spidered na jednostkę czasu i zwiększ lub zmniejsz maksymalną liczbę wątków w swoim ExecutorService, aż do maksymalizacji.

Jedną z rzeczy do rozważenia jest użycie NIO i selektorów, więc twoje wątki są zawsze zajęte, a nie zawsze czekają na IO. Oto good example tutorial about NIO/Selectors. Możesz również rozważyć użycie Pyronet, która wydaje się zapewniać pewne dobre cechy wokół NIO.

+0

Zastanawiam się. Kliknąłem na 'Pyronet' i mam około 150 pobrań. Dlaczego ktoś miałby bibliotekę z tak małą bazą użytkowników w ramach projektu? – Cratylus

+0

Zanim nie będzie żadnej alternatywy i nie chcesz ponownie wymyślać koła @Catatylus. :-) – Gray

1

Jeśli asynchroniczne operacje we/wy nie są dobrze dopasowane, rozważyłbym użycie pul wątków, np. ThreadPoolExecutor, więc nie masz narzutów w tworzeniu, niszczeniu i odtwarzaniu wątków.

Następnie wykonałbym testy wydajności, aby poprawić maksymalną liczbę wątków, zapewniając najlepszą wydajność.

Można rozpocząć od 10 wątków, a następnie powtórzyć test wydajności za pomocą 20 wątków, aż uzyskasz optymalną wartość. W tym samym czasie używałbym narzędzi systemowych (w zależności od systemu operacyjnego) do monitorowania kolejki wątków, JVM itp.

W celu wykonania testu wydajności należy upewnić się, że test jest powtarzalny (tj. Przy użyciu tych samych danych wejściowych) i reprezentuje rzeczywiste dane wejściowe, które będą używane przez twój program.

Powiązane problemy