Вызовы ядра NMI в замкнутом цикле

У меня есть тестовая программа

void task()
{
   long sum=0;
   while(true) {
      for(int i=0; i<100000;++i)
         for(int j=0; j < 10000; ++j)
            sum += j
   }
}
int main()
{
   boost::thread t(task);
   t.join();
   return true;
}

и я использую perf record -t -e intel_pt// для профилирования потока. Я вижу много вызовов НМИ, например, 2(?) вызова каждые несколько миллисекунд. Есть ли способ избавиться от этого типа прерываний? Centos 7, ядро ​​3.10.0, kernel.watchdog = 0.

РЕДАКТИРОВАТЬ на основе комментария @Zulan: версия gcc: 4.8.5. строка компиляции: g++ -I//include/ -L//lib -lboost_system -lboost_thread test.cpp Процессор Intel серии Platinum 8xxx/Gold 6xxx.
фрагмент вывода скрипта perf:

       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff816ac7f5 nmi ([kernel.kallsyms]) => ffffffff816ad500 do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff816ad54f do_nmi ([kernel.kallsyms]) => ffffffff816ad5f3 do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff816ad5fa do_nmi ([kernel.kallsyms]) => ffffffff8103dc10 is_debug_stack ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff8103dc62 is_debug_stack ([kernel.kallsyms]) => ffffffff816ad5ff do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff816ad60e do_nmi ([kernel.kallsyms]) => ffffffff816ad558 do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff816ad573 do_nmi ([kernel.kallsyms]) => ffffffff8113a3f0 rcu_nmi_enter ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff8113a41e rcu_nmi_enter ([kernel.kallsyms]) => ffffffff810ba170 __smp_mb__before_atomic ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff810ba17a __smp_mb__before_atomic ([kernel.kallsyms]) => ffffffff8113a423 rcu_nmi_enter ([kernel.kallsyms])
       a.out 25192 [009]  3976.829805:          1     branches:  ffffffff8113a427 rcu_nmi_enter ([kernel.kallsyms]) => ffffffff810ba180 __smp_mb__after_atomic ([kernel.kallsyms])
       ...
       a.out 25192 [009]  3976.829807:          1     branches:  ffffffff8113a4aa rcu_nmi_exit ([kernel.kallsyms]) => ffffffff8113a48a rcu_nmi_exit ([kernel.kallsyms])
       a.out 25192 [009]  3976.829807:          1     branches:  ffffffff8113a48c rcu_nmi_exit ([kernel.kallsyms]) => ffffffff816ad592 do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829807:          1     branches:  ffffffff816ad5ed do_nmi ([kernel.kallsyms]) => ffffffff816ad760 do_nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829807:          1     branches:  ffffffff816ad76e do_nmi ([kernel.kallsyms]) => ffffffff816ac7fa nmi ([kernel.kallsyms])
       a.out 25192 [009]  3976.829807:          1     branches:  ffffffff816ac804 nmi ([kernel.kallsyms]) => ffffffff816ac23c restore_args ([kernel.kallsyms])
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)

Еще один:

       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff816b6718 irq_work_interrupt ([kernel.kallsyms]) => ffffffff8102f620 smp_irq_work_interrupt ([kernel.kallsyms])
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff8102f629 smp_irq_work_interrupt ([kernel.kallsyms]) => ffffffff81090d20 irq_enter ([kernel.kallsyms])
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff81090d29 irq_enter ([kernel.kallsyms]) => ffffffff8113a360 rcu_irq_enter ([kernel.kallsyms])
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff8113a3a0 rcu_irq_enter ([kernel.kallsyms]) => ffffffff8113a3b8 rcu_irq_enter ([kernel.kallsyms])
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff8113a3c0 rcu_irq_enter ([kernel.kallsyms]) => ffffffff81137e10 rcu_eqs_exit_common.isra.31 ([kernel.kallsyms])
       ...
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff8113a27d rcu_irq_exit ([kernel.kallsyms]) => ffffffff8113a260 rcu_irq_exit ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff8113a26e rcu_irq_exit ([kernel.kallsyms]) => ffffffff81090e4e irq_exit ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff81090e50 irq_exit ([kernel.kallsyms]) => ffffffff8102f653 smp_irq_work_interrupt ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff8102f654 smp_irq_work_interrupt ([kernel.kallsyms]) => ffffffff816b671d irq_work_interrupt ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff816b671d irq_work_interrupt ([kernel.kallsyms]) => ffffffff816ac1ed ret_from_intr ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff816ac234 retint_swapgs ([kernel.kallsyms]) => ffffffff816ac23c restore_args ([kernel.kallsyms])
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)

grep'g для irq_return() из вывода скрипта perf показывает 3 прерывания за 20 мс.

           a.out 25192 [009]  3976.809174:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.809178:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.829808:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.829809:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.850317:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.850393:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.850395:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.870945:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           405764 task (a.out)
       a.out 25192 [009]  3976.870984:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.870985:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.891571:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.891609:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)
       a.out 25192 [009]  3976.891611:          1     branches:  ffffffff816ac26c irq_return ([kernel.kallsyms]) =>           40576f task (a.out)

в grub isolcpus, nohz_full, rcu_nocbs устанавливаются на конкретный процессор, а nmi_watchdog=0. тестовая программа запускалась с набором задач -c a.out.

Пожалуйста, предоставьте 1) версию компилятора 2) команду компиляции 3) фрагмент фактического perf script вывода 4) спецификацию процессора 4) сравнение с непоточной версией этого кода.

Zulan 13.06.2019 12:49

Какое железо/материнская плата? Получаете ли вы то же самое на разных аппаратных средствах с аналогичным программным обеспечением (если у вас есть другие машины с таким старым ядром)?

Peter Cordes 13.06.2019 17:04

NMI является механизм, используемый perf. Не используйте perf будет решением.

0andriy 14.06.2019 07:11

@ 0andriy, вы говорите, что они вставляются перфорационным процессом, а не самой программой? как это работает - a.out работает на ядре набора задач, а запись perf работает на другом. не могли бы вы уточнить? Спасибо

surfcode 14.06.2019 15:58

Не процесс пользовательского пространства perf; аппаратный PMU сообщает (программному коду ядра), что его буфер заполнен, используя прерывание NMI. Или для событий, не относящихся к PEBS, для выборки типа perf-record, прерывайте каждый раз, когда счетчик события переворачивается, потому что нет буфера. NMI-watchdog в Linux использует один из программируемых счетчиков PMU, так что это еще одно подтверждение того, что использование счетчиков производительности может генерировать NMI. (Есть и другие способы их использования, например, просто позволить им подсчитывать и собирать данные в конце, как это делает perf stat, но периодически может потребоваться сбор данных.)

Peter Cordes 14.06.2019 18:17

@Peter Cordes Спасибо, Питер. Изначально моя цель — сделать так, чтобы цикл спина не отнимал время у вызовов ядра или как можно меньше, поэтому параметр nohz_full. Так что же это за фиксированный таймер на 20 мс — он работает, настраивается? Спасибо

surfcode 15.06.2019 01:29

Как вы можете использовать intel_pt и получать доступ к grub на AWS?

BeeOnRope 15.06.2019 06:18

@BeeOnRope: посмотреть здесь

surfcode 17.06.2019 02:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
289
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего, если вы хотите трассировать ядро, вы получите много вызовов функций ядра в трассировке, включая, помимо прочего, связанные с NMI.

Если вы хотите отслеживать свою программу пользовательского пространства, как вы написали выше, используйте

perf record -t -e intel_pt//u ...

Лучше проконсультироваться с документацией https://elixir.bootlin.com/linux/latest/source/tools/perf/Documentation/intel-pt.txt

Однако эти вызовы, как сообщается, происходят на ЦП 9, на том же ЦП, что и моя программа, и за один раз они занимают микросекунды. Разве это не означает, что время тратится на вызовы NMI ядра вне моего спин-цикла? И если да, то как можно избавиться от прерываний nmi — моя цель — максимально убрать прерывания из спин-цикла. Первое, что я попробовал, это указать nohz_full в команде загрузки.

surfcode 15.06.2019 01:13

@surfcode: вы можете избавиться от них, нет запустив свою программу под perf record. Они являются частью того, как ядро ​​собирает данные PMU. то есть они являются частью накладных расходов, связанных с использованием intel_pt. Могут быть варианты использования больших буферов, чтобы они случались реже или что-то в этом роде...

Peter Cordes 15.06.2019 02:29

хорошо -- позвольте мне посмотреть, правильно ли я понимаю это. эти прерывания исходят от производительная запись. поэтому они обычно не существуют, если я не запускаю программу под производительная запись. звучит так, будто я хочу проверить прерывания по времени/аппаратным/часам/и т. д. после настройки системы, мне лучше использовать производительность или какие-то другие инструменты. Это правильно?

surfcode 15.06.2019 06:03

Другие вопросы по теме