Jak zrobić aby procek nic nie "robił"

0

Gdy komputer "nic" nie robi można zaobserwować, że obciążenie cpu wynosi 0%. Gdy uruchomi się prosty program:

skok:
jmp skok

To procek wbija na 100%(i np. w laptopach uruchamia Sie wiatraczek).
Więc jak to wszystko działa? Jak procek nie ma co robić to co robi? Przecież częstotliwość się nie zmniejsza, tylko ciągle klepie jakieś instrukcje. Są instrukcje, które bardziej i mniej obciążają procesor?
Gdyby napisać prosty system operacyjny(np. rmode) to jak by wyglądał fragment kodu żeby nie obciążał komputera?

0

Procesor wykonując pętle zawsze coś robi.
Takie zapętlenie też przecież musi być wykonywane przez procesor. Natomiast instrukcja HLT wprowadza procesor w stan bezczynności dopóki nie wystąpi jakiekolwiek przerwanie sprzętowe. Czyli jest to na pewno oszczędność użycia samego CPU.
System pokazuje wartości użycia CPU szacunkowo, a o samym pomiarze i jego błędzie przecież nic nie wiadomo ;)
a procesor jak już coś robi to przecież na 100% ;)

0

Dobry pomysł :-)
No więc w windowsie taki proces musi być wykonywany po każdej zmianie procesu.
Proces1
Proces z hlt
Proces2
Proces z hlt
Proces3
....
Aby nie przeciążać procka. Lecz jak jakiś program sporo ma do robienia no to już się procenty podnoszą.
I tu się właśnie zastanawiam.
Więc powyższa myśl raczej jest nie stosowana:

Tak sobie wymyśliłem że jak się uruchomi jakiś program(np. Microsoft Word) to na początku ma jakieś tam instrukcje do wykonania(stworzenie klawiszy menu itp), ale później wszystko się uspokaja czyli windows nie wykonuje już instrukcji w tym programie. Dopiero jak ruszymy myszką lub wciśniemy klawisz to system sprawdzi jaki program jest aktywny i wyśle do niego komunikat(czyli uruchomi instrukcje w tss tego procesu(a jak jest cisza to uruchamia proces z hlt i jest oczekiwanie do następnego przerwania systemowego lub innego), czyli jakąś procke która nasłuchuje komunikaty od windowsa).
Są też w programach timery, które też wykonują się poprzez komunikaty systemu. A więc jak jakiś program ma timer np. 1ms to procesor musi cały czas sobie liczyć kiedy minie 1ms, więc jakieś instrukcje wykonywać się muszą, chyba że to dla procka pikuś i prawie nic nie obciąża(bo chodzi razem z systemowym przerwaniem który przełącza procesy).

Dobrze myślę [???] :-)

0

Kliknięcie myszką czy chociażby poruszenie nią też prowadzi do przerwania, a jak robisz program konsolowy i czekasz na znak (wczytujesz coś z klawiatury lub innego miejsca) to procek jest na 100% obciążony? Wiesz raczej nie... Tak samo jest z myszą. Program czeka na przerwanie sprzętowe, gdy to nastąpi sprawdza czy to przerwanie było odpowiednim przerwaniem i jeśli tak to wykrywa o co w nim chodziło.

0

Zrobiłem przykładowy system z wykorzystaniem tej metody lecz nie działa, instrukcja jest jakby omijana.

void idle(){
  for(;;){
    printf("IDLE!\n");
    __asm__ __volatile__("sti \n\t hlt");
  }
}

Następnie uruchamiam to w tss o piorytecie 0, a na ekranie z góry na dół leci mi "IDLE".
A przecież procek powinien się zatrzymać na tej instrukcji [???]
Skoki do procesów są kontrolowane i podczas wykonywania tej funkcji nie są wykonywane żadne skoki, jedynie przy przerwaniu zegarowym wyświetlana jest liczba w rogu(zwiększana o 1 - mam pewność że działa). Myślę że to wina ustawień eflags lub czegoś czego nie wiem.
Proces idle jest oczywiście 32bitowy.

0

: Wyswietla sie to "IDLE!", robi sie halt, potem nastepuje przerwanie zegarowe w ktorym masz pewnie jakiegos schedulera, ktory cos tam robi, nastepnie wraca do twojego procesu i wszystko zaczyna sie od nowa (jmp).

Co w tym dziwnego?

0

No dokładnie :)

Procesor robi HLT, ale w momencie wystąpienia przerwania idzie je obsłużyć. Potem wraca do instrukcji następnej po HLT czyli wraca na początek pętli.

Wez spróbuj ten kod:

void idle(){
for(;;){
printf("IDLE!\n");
asm volatile("cli \n\t hlt");
printf("IDLE2!\n");
}
}

Wyłączyłem przerwania "cli".
Więc jeżeli HLT zawiesza komputer to nie powinno się wykonać printf("IDLE2!\n") bo nie wystąpi przerwanie. Zobacz sam czy tak będzie :)

0

No tak, ale jak dam sti i uruchomi się główny timer to ten napis się pojawi, nawet gdy funkcja od tego przerwania nic nie robi.
Ale problem rozwiązany, wcisłem w procek termometr i przy takim idle momentalnie zmniejsza się temperatura.
Zastanawia mnie jeszcze jak windows sobie oblicza prace cpu w %.
Ja wymyśliłem takie coś:

void hlt(){
  hlt_i++;
  __asm__ __volatile__("sti \n\t hlt");
}

hlt_i jest zmienną której zwiększam wartość za każdym razem gdy wykonam "hlt".
Następnie w głównym timerze będe sprawdzał ile funkcja hlt była wykonana(np. co 100 wywołanie timera), a następnie przelicze na procenty, i wyjdzie mi średnie obciążenie procka.
Dobre? :-)

0

No tak, ale jak dam sti i uruchomi się główny timer to ten napis się pojawi, nawet gdy funkcja od tego przerwania nic nie robi.

No i? o_O hlt zatrzymuje wykonywanie instrukcji dopoki cos sie nie wydarzy, cos - znaczy przerwanie, przerwanie sie wykonuje (sam napisales) wiec program leci dalej, o co chodzi?

Dobre? :-)

Po co tak kombinowac? Przeciez scheduler dobrze wie kiedy "proces" idle jest wykonywany, w ogole przeciez scheduler wie wszystko skoro sam to planuje, wiesz ile programow spi, jak dlugo spia itp etc, reszta to matematyka.

0
Wolverine napisał(a)

Po co tak kombinowac? Przeciez scheduler dobrze wie kiedy "proces" idle jest wykonywany, w ogole przeciez scheduler wie wszystko skoro sam to planuje, wiesz ile programow spi, jak dlugo spia itp etc, reszta to matematyka.

No tak, ale np. gdyby zrobić w procesie sleep(np. pętelka i liczy czy już dany czas upłyną) to byłoby to niepotrzebne obciążenie dla procka, więc można by zrobić w sleep takie coś:

void sleep(uint32 ms){
	ms /= 1000 / TIMER_FREQ;
	uint32 start = timer_step;          //timer_step++ gdy wykona się przerwanie(timer)
//trzeba jeszcze dopracowac bo mogą byc luki w przepelnieniu timer_step
	for(; timer_step < ms + start;)
		 __asm__ __volatile__("sti; hlt": : :"memory");
}//oczywiście sleep'a wykorzystuje sobie jakiś tam program

I tu dla scheduler'a proces chodzi, czyli procek 100%, a jednak proces w danym momencie wykorzystuje hlt w tej funkcji. I już mam błąd w oszacowaniu %, gdyż scheduler panował by nad samym procesem idle, chyba żeby te idle wywoływać w sleep'ie :-|

0

Przeciez taka funkcje jak Sleep nie robi sie po stronie usera, tylko jajka :/ Troche wyobrazni, nie po to jest scheduler zeby jak aplikacja chce spac to robi sobie while(1)hlt.

Takie pytanie male, z takim podejsciem po cholere ci w ogole proces idle? Skoro w Twojej architekturze nie ma czegos takiego jak "spiaca aplikacja"?

0

No to mam zrobić w schedulerze liste z procesami które śpią i ile mają spać?
Czy jak zrobić z tym np. sleepem?

0

Jak proces/watek zaczyna spac to po prostu ustawiasz jakas flage, dodajesz do listy czy jak to sobie tam zaimplementujesz i scheduler taki watek pomija dopoki spi, inaczej nie ma sensu w ogole robic czegos takiego jak idle (zwlaszcza, ze imo lepiej to zaimplementowac w ISRze timera zeby niepotrzebnie sie do 3 DPLa nie przelaczac).

Sprawiasz wrazenie, ze implementujesz pewne rzeczy tylko dlatego, ze "tak maja inni" :)

0
Wolverine napisał(a)

Jak proces/watek zaczyna spac to po prostu ustawiasz jakas flage, dodajesz do listy czy jak to sobie tam zaimplementujesz i scheduler taki watek pomija dopoki spi, inaczej nie ma sensu w ogole robic czegos takiego jak idle (zwlaszcza, ze imo lepiej to zaimplementowac w ISRze timera zeby niepotrzebnie sie do 3 DPLa nie przelaczac).

Sprawiasz wrazenie, ze implementujesz pewne rzeczy tylko dlatego, ze "tak maja inni" :)

Heh, nie do końca.
Tu właśnie z tym sleepem sie namieszało.
Zrobiłem tak że gdy proces coś tam sobie już zrobi to wywołuje pewną funkcję "nasłuchującą". Funkcja wyłącza proces, że scheduler go pomija. Dopiero jak przyjdzie przerwanie lub coś podobnego to proces jest budzony do życia i przesyłany jest do niego komunikat(wywołuje się funkcja nasłuchująca i zaś jak się tam już wykona to proces się usypia). Gdy nie ma żadnego procesu który nie śpi to wykonywany jest proces IDLE.
Taki efekt jest w windowsie przy procedurze GetMessage(czy jakoś tak).
Jeszcze troche pomyśle jak to wszystko skleić do kupy.

0

No to teraz zrob to samo z funkcja sleep, tylko zamiast na przerwanie niech sie budzi po okreslonym odcinku czasowym :)

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