2012-02-09 14 views
13

Obecnie studiuję na temat harmonogramu Linuksa. Jeśli chodzi o powinowactwo do rdzeni procesora, chciałbym wiedzieć, co następuje:W jaki sposób każdy proces jest przypięty do określonego rdzenia za pomocą programu szeregującego (Linux)

1) W jaki sposób każdy proces (wątek) jest przypięty do rdzenia?

Istnieje wywołanie systemowe sched_setaffinity w celu zmiany powinowactwa głównego, w którym wykonywany jest proces. Ale wewnętrznie, kiedy generowany jest proces (lub wątek), w jaki sposób domyślny harmonogram linuksowy przypisuje proces (wątek) do określonego rdzenia? Zmodyfikowałem sched_setaffinity wywołanie systemowe, aby zrzucić informacje o przenoszeniu zadania z jednego jądra do drugiego.

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid, 
             current->state, current->cpus_allowed, 
             current->comm); 

Wygląda na to, że nie ma żadnego zrzutu powyższych informacji w /var/log/messages. Domyślny harmonogram przypisuje każdy proces w inny sposób, ale nie wiem, jak to zrobić.

2) Czy można uzyskać identyfikator rdzenia za pomocą PID lub innych informacji?

To jest to, co chcę zaimplementować w jądrze Linuksa. W dokumencie task_struct znajduje się element o nazwie cpus_allowed. Ale jest to maska ​​do ustawienia powinowactwa, a nie core ID. Chcę pobrać dane identyfikujące rdzeń, na którym działa określony proces.

Dzięki,

Odpowiedz

0

Przybliżenie rdzenia procesora zależy od systemu operacyjnego. System operacyjny wie, jak to zrobić, nie musisz. Możesz napotkać różnego rodzaju problemy, jeśli określisz, który rdzeń ma być uruchomiony, a niektóre z nich mogą spowolnić proces.

W jądrze Linux struktura danych powiązana z procesami task_struct zawiera cpu_allowed pole maski bitowej. Zawiera n-bitów po jednym dla każdego z n procesorów w maszynie. Maszyna z czterema rdzeniami fizycznymi miałaby cztery bity. Jeśli te rdzenie procesora byłyby wyposażone w funkcję hyperthread, miałyby ośmiobitową maskę bitową. Jeśli dany bit jest ustawiony dla danego procesu, proces ten może działać na powiązanym rdzeniu. Dlatego, jeśli proces może być uruchamiany na dowolnym rdzeniu i może migrować pomiędzy procesorami w razie potrzeby, maska ​​bitowa będzie w całości 1s. Jest to w rzeczywistości stan domyślny dla procesów w systemie Linux. Na przykład:

PID 2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3 

proces 2441 ma powinowactwo CPU równe 0x3, co oznacza, że ​​może być używane w Core0 i Core1.

Aplikacje mogą również określać/ustawiać powinowactwo za pomocą interfejsu API sched_set_affinity() zmieniając maskę bitową.

+0

Dziękuję za odpowiedź. Ale to jest coś innego, czego chcę. Zastanawiam się, czy mój opis wprowadza w błąd ... Po pierwsze, nie używam wywołania systemowego 'sched_setaffinity' (nie sched_set_affinity, ale sched_setaffinity), ponieważ nie tworzę aplikacji działającej w przestrzeni użytkownika. – akry

+0

Po drugie, pole 'cpus_allowed' (not cpu_allowed) nie jest wystarczającą informacją, aby zidentyfikować rdzeń procesora, na którym działa proces. cpus_allowed jest domyślnie ustawiony na 1, więc proces prawdopodobnie przeniesie wszystkie dostępne rdzenie. Jeśli istnieje jakieś pole/metoda informujące o miejscu, w którym proces jest uruchomiony, naprawdę to chcę wiedzieć. – akry

+0

W każdym razie, dziękuję za odpowiedź na moje pytanie. – akry

4

Każdy procesor ma swoją własną, AFAIK, którą możemy znaleźć na bieżącym procesorze procesu, szukając, do której klasy należy. Biorąc pod uwagę task_struct *p, możemy uzyskać jego runqueue przez struct rq = task_rq(p), a struct rq ma pole o nazwie cpu, myślę, że to powinna być odpowiedź.

Nie próbowałem tego w praktyce, po prostu przeczytaj jakiś kod w Internecie i nie jestem całkiem pewien, czy to zadziała, czy nie. Chciałbym ci pomóc.

+0

Dziękuję za odpowiedź. Dam ci znać po wypróbowaniu tej metody. – akry

+1

Należy zauważyć, że jest to dość agresywne - zadanie może zostać przeniesione z jednego runqueue do drugiego pod tobą. – caf

2

Pole 39 w pozycji /proc/pid/stat mówi bieżący klucz/procesor procesu.

np .:

#cat /proc/6128/stat 
6128 (perl) S 3390 6128 3390 34821 6128 4202496 2317 268 0 0 1621 59 0 0 16 0 1 0 6860821 10387456 1946 18446744073709551615 1 1 0 0 0 0 0 128 0 18446744073709551615 0 0 17 8 0 0 0 

Proces 6128 działa w rdzeniu 8.

2

Można określić identyfikator procesora, na którym wątek jest uruchomiony przy użyciu jego task_struct:

#include <linux/sched.h> 

task_struct *p; 
int cpu_id = task_cpu(p);