2012-02-09 24 views
13

Tôi hiện đang nghiên cứu về lịch trình của Linux như thế nào. Về mối quan hệ cốt lõi của CPU, tôi muốn biết những điều sau đây:Mỗi quá trình được gắn vào một lõi cụ thể bằng cách lên lịch (Linux)

1) Mỗi ​​quy trình (luồng) được gắn vào lõi như thế nào?

có một hệ thống gọi sched_setaffinity để thay đổi mối quan hệ cốt lõi mà trên đó một quá trình được thực hiện. Nhưng trong nội bộ, khi một tiến trình (hoặc một luồng) được tạo ra, thì trình lên lịch Linux mặc định gán quy trình (luồng) cho một lõi cụ thể như thế nào? Tôi đã sửa đổi sched_setaffinity cuộc gọi hệ thống để kết xuất thông tin về nhiệm vụ đang được chuyển từ lõi này sang lõi khác.

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

Dường như không có thông tin trên ở đây trong /var/log/messages. Vì vậy, trình lên lịch mặc định ghim từng quy trình theo một cách khác, nhưng tôi không thể tìm ra cách.

2) Có thể lấy ID lõi của PID hoặc thông tin khác không?

Đây là những gì tôi muốn triển khai bên trong nhân Linux. Trong số task_struct, có một thành viên được gọi là cpus_allowed. Nhưng đây là mặt nạ để đặt mối quan hệ chứ không phải ID lõi. Tôi muốn lấy một dữ liệu xác định lõi mà quy trình được chỉ định đang chạy.

Cảm ơn,

Trả lời

0

CPU lõi ái lực là hệ điều hành cụ thể. Các hệ điều hành biết làm thế nào để làm điều này, bạn không phải. Bạn có thể chạy vào tất cả các loại vấn đề nếu bạn chỉ định lõi nào để chạy, một số trong đó có thể thực sự làm chậm quá trình.

Trong hạt nhân Linux, cấu trúc dữ liệu được liên kết với các quy trình task_struct chứa trường bitmask cpu_allowed. Điều này chứa n bit một cho mỗi bộ xử lý n trong máy. Một cỗ máy có bốn lõi vật lý sẽ có bốn bit. Nếu những lõi CPU này được kích hoạt thì chúng sẽ có một bitmask 8 bit. Nếu một bit đã cho được thiết lập cho một quá trình đã cho, quá trình đó có thể chạy trên lõi được liên kết. Do đó, nếu một quy trình được phép chạy trên bất kỳ lõi nào và được phép di chuyển qua các bộ xử lý nếu cần, bitmask sẽ hoàn toàn là 1s. Đây là thực tế, trạng thái mặc định cho các tiến trình trong Linux. Ví dụ:

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

quy trình 2441 có ái lực CPU 0x3, có nghĩa là nó có thể được sử dụng trong Core0 và Core1.

Các ứng dụng cũng có thể chỉ định/đặt ái lực bằng cách sử dụng API hạt nhân sched_set_affinity() bằng cách thay đổi bitmask.

+0

Cảm ơn bạn đã trả lời của bạn. Nhưng điều này khác với những gì tôi muốn. Tôi đã tự hỏi nếu mô tả của tôi là gây hiểu lầm ... Trước hết, tôi không sử dụng lệnh gọi hệ thống 'sched_setaffinity' (không phải sched_set_affinity nhưng sched_setaffinity) vì tôi không tạo một ứng dụng đang chạy trong không gian người dùng. – akry

+0

Thứ hai, trường 'cpus_allowed' (không phải cpu_allowed) không đủ thông tin để xác định lõi CPU mà quá trình đang chạy. cpus_allowed được đặt là 1 theo mặc định để quá trình có khả năng di chuyển tất cả các lõi có sẵn. Nếu có bất kỳ trường/phương thức nào nói cho vị trí nơi tiến trình đang chạy, đây là điều tôi thực sự muốn biết. – akry

+0

Dù sao, cảm ơn bạn đã trả lời câu hỏi của tôi. – akry

4

Mỗi CPU có runqueue riêng của mình, AFAIK chúng tôi có thể tìm ra CPU hiện tại của một quá trình bằng cách tìm kiếm runqueue nó thuộc về. Với task_struct *p, chúng tôi có thể lấy runqueue của nó bằng struct rq = task_rq(p) và struct rq có một trường có tên là cpu, tôi đoán đây là câu trả lời.

Tôi đã không thử điều này trong thực tế, chỉ cần đọc một số mã trực tuyến, và tôi không hoàn toàn chắc chắn nó sẽ hoạt động hay không. Muốn nó có thể giúp bạn.

+0

Cảm ơn bạn đã trả lời. Tôi sẽ cho bạn biết sau khi tôi thử phương pháp này. – akry

+1

Lưu ý rằng điều này là đáng tin cậy - nhiệm vụ có thể được di chuyển từ một runqueue khác bên dưới bạn. – caf

2

Trường 39 trong /proc/pid/stat cho lõi/CPU hiện tại của quy trình.

ví dụ .:

#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 

Process 6128 đang chạy trên lõi 8.

2

Bạn có thể xác định ID CPU mà a thread đang chạy bằng cách sử dụng task_struct của nó:

#include <linux/sched.h> 

task_struct *p; 
int cpu_id = task_cpu(p); 
Các vấn đề liên quan