nonvoluntary_ctxt_switches для RT процесса и прерывания.

Phoenix

Хочу сделать busyloop на одном ядре в linux.
 
#mpstat -I ALL
Average: CPU intr/s
Average: all 630.05

Average: CPU 0/s 1/s 8/s 9/s 12/s 16/s 18/s 19/s 21/s 23/s 64/s 85/s 86/s 87/s 88/s 89/s 90/s 91/s 92/s 93/s 94/s 95/s 96/s 106/s 107/s 108/s 109/s 110/s 111/s 112/s 113/s 114/s 115/s 116/s 117/s 127/s 128/s 129/s 130/s 131/s 132/s 133/s 134/s NMI/s LOC/s SPU/s PMI/s IWI/s RTR/s RES/s CAL/s TLB/s TRM/s THR/s MCE/s MCP/s ERR/s MIS/s
...
Average: 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 251.95 0.00 0.00 0.05 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
...
Average: CPU HI/s TIMER/s NET_TX/s NET_RX/s BLOCK/s BLOCK_IOPOLL/s TASKLET/s SCHED/s HRTIMER/s RCU/s
Average: 0 0.00 8.48 0.00 0.00 1.24 0.00 0.00 148.86 0.00 6.67
Average: 1 0.00 250.05 0.00 0.00 0.00 0.00 0.00 1.76 0.00 40.00
Average: 2 0.00 2.33 0.00 0.00 0.00 0.00 0.00 0.57 0.00 2.29
Average: 3 0.00 1.29 0.00 0.00 0.00 0.00 0.00 0.29 0.00 1.24
Average: 4 0.00 2.90 0.00 0.00 1.05 0.00 0.00 0.48 0.00 2.86
Average: 5 0.00 1.67 0.00 0.00 0.95 0.00 0.00 0.33 0.00 1.62
Average: 6 0.00 36.62 0.14 84.48 6.00 0.00 9.29 18.19 0.00 21.38
Average: 7 0.00 23.10 0.19 0.24 0.00 0.00 0.00 15.57 0.00 13.05
Average: 8 0.00 3.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.52
Average: 9 0.00 14.95 0.00 0.00 0.00 0.00 0.00 0.62 0.00 10.38
Average: 10 0.00 4.48 0.00 0.00 0.00 0.00 0.00 0.10 0.00 2.67
Average: 11 0.00 2.71 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.90

# grep ctx /proc/22919/status
voluntary_ctxt_switches: 88
nonvoluntary_ctxt_switches: 2

# top
top - 22:52:57 up 4 days, 11:01, 5 users, load average: 1.92, 1.49, 1.08
Tasks: 189 total, 3 running, 186 sleeping, 0 stopped, 0 zombie
%Cpu(s): 7.9 us, 1.6 sy, 0.0 ni, 90.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 24736876 total, 23702972 used, 1033904 free, 341388 buffers
KiB Swap: 98023416 total, 12 used, 98023408 free. 22512180 cached Mem

22919 igor -26 0 25524 3808 3564 R 1 97.4 0.0 1:47.01 client_m

# chrt -p 22919
pid 22919's current scheduling policy: SCHED_FIFO
pid 22919's current scheduling priority: 25


Как я понимаю, срабатывает LOC один раз в 4 мс и видит, что ничего приоритетнее, чем текущий RT процесс нет. не прерывает его.
вопрос: прерывание есть, nonvoluntary_ctxt_switches не меняется, т.е. переключения нет. Почему?
Как бы 250 убрать? и делать это прерывание, например, по запросу пользователя (когда он хочет kill сделать и т.п.)

beluchy

какой вопрос - такой ответ =)

$ git grep nivcsw
fs/proc/array.c: p->nivcsw);
include/linux/compat.h: compat_long_t ru_nivcsw;
include/linux/sched.h: unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
include/linux/sched.h: unsigned long nvcsw, nivcsw; /* context switch counts */
include/uapi/linux/resource.h: __kernel_long_t ru_nivcsw; /* involuntary " */
include/uapi/linux/taskstats.h: __u64 nivcsw; /* nonvoluntary_ctxt_switches */
kernel/compat.c: __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
kernel/exit.c: sig->nivcsw += tsk->nivcsw;
kernel/exit.c: psig->cnivcsw +=
kernel/exit.c: p->nivcsw + sig->nivcsw + sig->cnivcsw;
kernel/fork.c: tsk->nvcsw = tsk->nivcsw = 0;
kernel/fork.c: tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
kernel/hung_task.c: unsigned long switch_count = t->nvcsw + t->nivcsw;
kernel/sched/core.c: switch_count = &prev->nivcsw;
kernel/sched/debug.c: (long long)(p->nvcsw + p->nivcsw),
kernel/sched/debug.c: nr_switches = p->nvcsw + p->nivcsw;
kernel/sched/debug.c: "nr_involuntary_switches", (long long)p->nivcsw);
kernel/sys.c: r->ru_nivcsw += t->nivcsw;
kernel/sys.c: r->ru_nivcsw = p->signal->cnivcsw;
kernel/sys.c: r->ru_nivcsw += p->signal->nivcsw;
kernel/taskstats.c: stats->nivcsw = tsk->nivcsw;
kernel/taskstats.c: stats->nivcsw += tsk->nivcsw;

Phoenix

намекаешь на это?
 
 2793         if (likely(prev != next)) {
2794 rq->nr_switches++;
2795 rq->curr = next;
2796 ++*switch_count;
2797
2798 rq = context_switch(rq, prev, next); /* unlocks the rq */
2799 cpu = cpu_of(rq);
2800 } else
2801 raw_spin_unlock_irq(&rq->lock);

А скидывает ли это кэш? Это переключение контекста считается (user->core->user) ?
Какие способы оценить, на сколько прерывается приложение каждые 4ms?
По какому слову нужно grep запустить, чтобы понять, когда ставится новое "задание" на прерывание через 4ms и как можно убрать-то (вроде это и был вопрос ;) ?
PS: Раньше я оценивал ущерб от прерываний так: смотрел, поменялся ли счётчик переключений и замерял время от предыдущего замера, считал среднее для меняется/не меняется и смотрел разницу. А сейчас он не меняется :o

Marinavo_0507

CONFIG_NO_HZ_FULL не помогает?

beluchy

я ни на что не намекаю, я просто ничего не понял :p
ты хочешь знать какую часть процессорного времени съедает ОС?
Чем тебя не устраивает, например, "астрономическое время" - "user CPU time used"?

procenkotanya

> как можно убрать-то
Ты хочешь full tickless, видимо?

Phoenix

Да, друзья! Походу, это оно. Как потестю, напишу.

beluchy

интересно, чем ты таким занимаешься, что наносекунды считаешь?

Phoenix

сам себе задаю тот же вопрос постоянно

vall

у меня дежавю, ты уже вроде страдал с рт-бизилупом?

Phoenix

Ага. И вот видишь, как жизнь поменялась. Пока я нашёл, как не увеличивать счётчик переключений, уже в ядро опцию вмонтировали. и плюс, это не приоритетная задача, поэтому она всплывает, когда остальные сделаны осточертели
Оставить комментарий
Имя или ник:
Комментарий: