2010-01-17 9 views
8

Napisałem bibliotekę C++, która wykonuje kilka poważnie ciężkich zadań procesora (wszystko to z matematyki i obliczeń) i jeśli zostawi się je własnemu urządzeniu, z łatwością zużyje 100% wszystkich dostępnych zasobów procesora (jest również wielowątkowe do liczby dostępne rdzenie logiczne na komputerze).Najlepszy sposób na spowolnienie wątku? Czy używasz trybu uśpienia()?

Jako takie, mam zwrotnego wewnątrz pętli głównej obliczeniowego, że oprogramowanie z biblioteki ma zadzwonić:

while(true) 
{ 
    //do math here 
    callback(percent_complete); 
} 

w wywołanie zwrotne, klient zwraca uśpienia (x), aby spowolnić wątek.

Pierwotnie kod klienta był stałym wywołaniem funkcji Sleep (100), ale doprowadziło to do złej zawodności, ponieważ niektóre maszyny kończą matematykę szybciej niż inne, ale sen jest taki sam na wszystkich komputerach. Teraz klient sprawdza czas systemowy, a jeśli minęło więcej niż 1 sekundę (co == kilka iteracji), będzie spał przez pół sekundy.

Czy jest to dopuszczalny sposób spowolnienia wątku? Czy powinienem używać semafora/mutex zamiast Sleep(), aby zmaksymalizować wydajność? Czy spanie x milisekundy na każdą 1 sekundę obróbki działa dobrze, czy coś jest nie tak, czego nie dostrzegam?

Powodem, dla którego pytam, jest to, że maszyna nadal jest mocno zagłuszana, mimo że Taskman pokazuje proces zajmujący około 10% CPU. Już odkryłem rywalizację o dysk twardy i pamięć bez skutku, więc teraz zastanawiam się, czy przyczyną tego problemu jest sposób, w jaki spowalniam wątek.

Dzięki!

Odpowiedz

2

Uśpienie powinno być dobre dla dławienia aplikacji, która z twoich komentarzy jest tym, czego szukasz. Być może po prostu musisz być bardziej precyzyjny, jak długo będziesz spać.

Jedyne oprogramowanie, w którym używam takiej funkcji, to BOINC client. Nie wiem, jakiego mechanizmu używa, ale jest open-source i wieloplatformowy, więc pomóż sobie.

Posiada opcję konfiguracji ("Ogranicz użycie procesora do X%"). Sposobem, w jaki spodziewam się tego zaimplementować, jest użycie interfejsowych interfejsów API, takich jak clock() lub GetSystemTimes(), i porównanie czasu procesora z czasem zegara ściennego. Wykonaj trochę prawdziwej pracy, sprawdź, czy masz więcej lub więcej niż przeciętny, i jeśli masz spać przez jakiś czas, by wrócić.

Klient BOINC ładnie gra z priorytetami i nie powoduje żadnych problemów z wydajnością w przypadku innych aplikacji, nawet przy maksymalnym obciążeniu procesora 100%. Powodem, dla którego używam przepustnicy jest to, że w przeciwnym razie klient cały czas uruchamia procesor i zwiększa prędkość i hałas wentylatora. Więc uruchamiam go na poziomie, na którym wentylator pozostaje cichy. Lepsze chłodzenie może nie będzie mi potrzebne :-)

+0

W systemie Linux, jeśli uruchomisz proces na wyższym, ładnym poziomie, system operacyjny będzie utrzymywał niski poziom zegara procesora, zakładając, że twój sprzęt obsługuje skalowanie szybkości procesora. Pozwoli to utrzymać niski poziom mocy, ciepła i hałasu bez sztucznego dławienia. – karunski

+0

Słodki. Przejście na Linuksa jest opcją, którą stale rozważam i jak dotąd zawsze odrzucam ... –

23

Dlaczego nie używasz niższego priorytetu dla wątków obliczeniowych? Zapewni to zaplanowanie innych wątków, pozwalając wątkom obliczeniowym działać tak szybko, jak to możliwe, jeśli nie będą potrzebne żadne inne wątki.

+4

W praktyce nie jest to niezawodne w systemie Windows. Przesłałem bibliotekę do OS X i tam działa jak marzenie o niższym priorytecie, ale w systemie Windows nadal będzie powodować problemy. Również coś jeszcze: dla celów marketingowych/wsparcia technicznego uważamy, że nie powinno się oprogramowania zajmować więcej niż 20% CPU w menedżerze zadań, albo dostajesz szalone skargi i dziwaczne recenzje o zabijaniu oprogramowania Wydajność komputera. Ludzie widzą 50% użycia procesora i panikę! –

+1

Nie mogę powiedzieć, dlaczego twój port zachowywał się podobało. Z mojego doświadczenia wynika, że ​​planowanie działa dobrze w systemie Windows. W każdym razie, biorąc pod uwagę pytanie, które moim zdaniem najlepiej jest rozwiązać przy użyciu priorytetów i pozostawienia planowania systemu operacyjnego. –

+11

Guru komputera, priorytety wątków działają całkiem niezawodnie w systemie Windows. Jeśli jednak wykonujesz wiele operacji we/wy (nie ma znaczenia, czy są one bezpośrednie, czy spowodowane stronicowaniem pamięci), możesz również zmniejszyć priorytet wejścia/wyjścia. Zobacz SetThreadPriority i THREAD_MODE_BACKGROUND_BEGIN. – avakar

0

Zobacz cpulimit. Wysyła SIGSTOP i SIGCONT zgodnie z wymaganiami, aby utrzymać proces poniżej określonego procentu użycia procesora.

Nawet nadal, WTF na "szalone skargi i dziwaczne recenzje na temat twojego oprogramowania zabijającego wydajność komputera". Byłbym bardziej skłonny narzekać, że twoje oprogramowanie działało wolno i nie korzystało najlepiej z mojego sprzętu, ale nie jestem twoim klientem.

Edycja: w systemie Windows, SuspendThread() i ResumeThread() może prawdopodobnie powodować podobne zachowanie.

0

Inną, niezbyt skomplikowaną metodą może być odmierzenie jednej iteracji i pozostawienie wątku przez sen (x * t) milisekund przed następną iteracją, gdzie t jest milisekundą dla jednej iteracji, a x jest wybraną frakcją czasu uśpienia (od 0 do 1).

4

Co jest nie tak z procesorem przy 100%? Właśnie tego powinieneś dążyć, a nie próbować tego uniknąć. Te obliczenia matematyczne są ważne, nie? Chyba że starasz się uniknąć noszenia jakiegoś innego zasobu, który nie jest jawnie zarządzany przez system operacyjny (muteks, dysk itp.) I jest używany przez główny wątek, generalnie próbując spowolnić wątek, jest to zły pomysł. A co powiesz na systemy wielordzeniowe (które będą dotyczyły niemal wszystkich systemów)? Zwolniłbyś wątek bez żadnego powodu.

System operacyjny ma pojęcie kwantu wątku. Zadba o to, aby żaden ważny wątek w twoim systemie nie został zagłodzony. I, jak już wspomniałem, w systemach wielordzeniowych wygrywanie jednego wątku na jednym procesorze nie szkodzi wydajności innym wątkom na innych rdzeniach.

Widzę również w innym komentarzu, że ten wątek również wykonuje wiele operacji we/wy dysku - te operacje spowodują już, że wątek ulegnie zniszczeniu, podczas gdy oczekuje na wyniki, więc śpi nic nie zrobią.

Ogólnie, jeśli dzwonisz do trybu uśpienia (x), jest coś złego/leniwego w swoim projekcie, a jeśli x == 0, otwierasz się do blokad na żywo (wątek wywołujący uśpienie (0)) może być w rzeczywistości odroczona natychmiast, co czyni ją odlotową).

+0

Być może pomoże ci odrobina kontekstu: matematyka polega na obliczeniu minimalnej różnicy między dwoma plikami dla programu kopii zapasowej. Program do tworzenia kopii zapasowych "ustaw to i zapomnij" nie powinien zajmować 100% CPU, podczas gdy program "diff plikowy" powinien służyć jednemu celowi. W tym tkwi klucz do tego projektu :) –

+1

Ah, widzę; właśnie dlatego wynaleziono priorytety procesów i zamówień. Powinieneś to zrobić i niech programista OS zajmie się sprawami. Pomiń Sleos. –

+3

Myślę, że Computer Guru mówi, że jego program do tworzenia kopii zapasowych nie powinien przyjmować 100% CPU, * nawet jeśli system jest zupełnie bezczynny *. Karunski mówi, że linux osiąga to właśnie poprzez przypisywanie dostatecznie niskiego priorytetu, ale nie jest tym, jaki priorytet ma w POSIX znaczeniu. Istnieje różnica między względnym priorytetem wśród procesów ("nie rób tego szybko, jeśli zagłodziłoby coś ważnego") i jak sądzę, możesz nazwać absolutny priorytet ("nie rób tego szybko, nigdy"). –

Powiązane problemy