리눅스 커널의 스케쥴링 오버헤드를 측정하고 싶다.

swhong의 이미지

만약 이러한 사람이 있다고 가정을 해보면요,

하나의 process가 cpu에서 수행이 되다가 context switch가 발생하여,
cpu에서 내려가게 되지요, 이때 이 process가 다시 cpu를 얻기까지의 시간이 얼마나 걸리는지를 측정하고 싶다면, 어떤 방법이 있을까요?

커널레벨에서 이것을 모든 프로세스에 대해 적용하여 측정을 할 수 있을까요?

요즘 리눅스 커널 열씨미 공부하고 있는데, 무지 궁금한 것들이 많아서요...
해보구 싶은게 많아서.... 잠도 안와요....

mushim의 이미지

프로세스마다 rusage 라는 구조체가 정의 되어 있는데

이 항목중에 context siwtch 항목이 있습니다.

이 값을 읽는 방법은 getrusage 시스템콜을 이용하면 됩니다.

그런데, 아직 리눅스에서는 구현이 되어 있지 않습니다.

그렇게 어려워 보이지는 않은데...

만약, 커널을 건드리신다면 context switching 일어날때마다,

이전 프로세스의 rusage 의 context switch 항목을 하나씩 증가시키면 될 것 같네요.

swhong의 이미지

님의 말씀을 이해하기로는 rusage구조체 부분의 ru_nvcsw 와 ru_nivcsw을 이용하라는 말씀이고, 이 값을 건드려주는 interface가 아직 구현되어있지 않다라는 이야기로 이해했는데....잘 이해를 했는지 모르겠습니다.

궁금한 것이 있는데, 혹시 scheduling하면서 context switching이 일어나는 code의 path를 대충 설명해주실 수 있나요? 커널 소스 계속 주~욱 따라가 보는데, 영 감이 안와서 조금 가이드를 해주실 고수님....

제가 먼저 찾으면 얼렁 올릴께요~

- by swhong in jgdr.net -

mushim의 이미지

우선 제가 잘못 표현했군요.

프로세스마다 rusage 라는 구조체가 있다는 말은 잘못되었구요.

프로세스마다 task_struct 라는 구조체가 있는데, 이 구조체의 항목들을 이용해서 rusage 구조체의 값을 만들게 되네요.

그런데, task_struct 에 context switch 개수에 대한 정보가 없기 때문에 getrusage 시스템콜에서도 ru_nvcsw 와 ru_nivcsw 에 대한 값을 구현 못한것이네요.

만약 만드신다고 하면, 일단 task_struct 에 context switch 에 대한 항목을 추가하셔야 하구요. (include/linux/sched.h)

fork/exit 할때 초기화/최종계산을 수행해야 하고, (kernel/fork.c ,kernel/exit.c )

schedule() 루틴에서 task_struct pointer 인 prev 의 상태에 따라서, coext switch 의 값을 증가하면 될것입니다. prev->stat 가 TASK_RUNNIG 이면 비자발적, 아니면 자발적 context switch 의 값을 증가시키면 됩니다. (kernel/sched.c)

마지막으로, sys_getrusage 가 내부에서 호출하는 getrusage() 함수를 수정하면 될것입니다. (kernel/sys.c)

swhong의 이미지

지금 마구 찾아보면서 코드를 삽입하려고 하는 중입니다. 오....기대되어라...

그런데, 이것은 몇번의 context switching을 당하느냐만 측정을 할 수 있겠군요...

저는 context switching으로 낭비하는 총 시간을 구하고 싶은데요,

그래서 생각해낸 제 스스로의 과제는...ㅋㅋ

여러 프로세스들이 있지않습니까?

프로세스 종류별로 각각의 프로세스가 그 수행을 하기까지 평균 얼마의 시간을 context switching으로 인해 중단되어 소비하는가를 측정하는 것입니다.

그러니까, 프로세스 종류별로 허비하는 시간을 알아보고 싶은 것이죠...

그래서,

1. pid와 time 그리고 flag을 저장할 수 있는 전역 구조체 배열을 하나 만든다.

2. 구조체 배열에 switching이 되어 올라온 프로세스가 prev 프로세스의 pid와 현재 시간을 저장한다.

3. switching out된 프로세스는 다음번에 올라올땐 같은 동작과 함께 자신의 pid를 그 구조체 배열에서 찾은후, 시간차이를 계산한 결과를 다시 저장시킨후 flag를 1로 켠다.

다음부터는 자신의 pid중 flag가 0인 것만 조사하면 됩니다.

움, 그런데... 이 코드를 어디에다가 삽입하면 좋을지....고민입니다.

프로세스가 job을 수행하기 전에 항상 이 일을 해주어야 할 텐데 말이죠...

아...머리아포라.....

- by swhong in jgdr.net -

sliver의 이미지

task_struct에

마지막으로 switched out한 시간 last_time 필드와

지금까지 context switch간의 시간들의 합인 switch_time 필드를 추가하는

것이 좋은 방법일 것 같습니다.

kernel/sched.c에 보면

schedule()함수가 있습니다.

그 함수 중간에

switch_to(prev,next,prev); 매크로를 호출합니다.

이 매크로에서 실제 context switch가 발생합니다.

따라서 switch_to호출 직전에,

current->last_time에 현재시간(jiffies)를 저장하고,

switch_to호출 다음에,

time_diff=현재시간(jiffies) - current->last_time를 계산하여 그 시간차이를 구하고

current->switch_time += time_diff;

이렇게 해주면 될 것 같습니다.

참고로 jiffies는 각 timer interrupt때마다 1씩 증가합니다.

HZ 매크로는 초당 발생하는 timer interrupt수를 나타냅니다.

따라서 switch_time/HZ를 계산하면 초 단위로 결과를 얻을 수 있습니다.

그리고 last_time이나 switch_time 이런 변수는

kernel/fork.c 파일의 do_fork함수에서 초기화 해주면 됩니다.

2.2.x버전을 기준으로 말씀드렸는데 2.4.x는 잘 모르겠지만 비슷할 것 같습니다.

swhong의 이미지

schedule_to 함수 이전에 시간값을 저장한다는 생각을 저도 했는데.... 와!!

시간은 task_struct에 저장하는 것이 효과적이겠군요...흠흠..

그런데, 말씀중에 궁금한 것이 있는데요...

switch_to호출 다음에, 

time_diff=현재시간(jiffies) - current->last_time를 계산하여 그 시간차이를 구하고 

라고 말씀을 하셨는데요....

제가 이것을 이해한 바로는, switch_to 매크로 호출 이후의 코드 즉,

         switch_to(prev, next, prev);
         // 바로 요부분!!!
         __schedule_tail(prev);

__schedule_tail(prev)부터 교체된(context switching을 거쳐 새로이 cpu를 얻은) Process 가 current에 올라와있다.....

그러므로 새로 올라온 프로세스에 대해 측정을 가할 부분이.....

switch_to를 호출한 이후에 current가 바뀌게 되므로
거기서(바로 요부분!!! 이라고 표시한 곳) 새로 올라온 current에 대해 측정을 하면 된다는 이야기 이군요....

정말 감사합니다.
감사합니다....

- by swhong in jgdr.net -

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.