Как я могу получить номер ядра ЦП из приложения пользовательского пространства (Linux, C)? - PullRequest
17 голосов
/ 29 января 2009

Предположительно, есть библиотека или простой asm-объект, который может получить номер текущего процессора, на котором я выполняю.

Ответы [ 4 ]

21 голосов
/ 29 января 2009

Используйте sched_getcpu для определения ЦП, на котором работает вызывающий поток. См. man getcpu (системный вызов) и man sched_getcpu (оболочка библиотеки). Однако обратите внимание, что там написано:

Информация, помещаемая в процессор, гарантированно актуальна только во время вызова: если сродство ЦП не было установлено с помощью sched_setaffinity (2), ядро ​​может изменить ЦП в любое время. (Обычно этого не происходит, потому что планировщик пытается минимизировать перемещения между процессорами, чтобы держать кеши горячими, но это возможно.) Вызывающий должен быть готов обработать ситуацию, когда процессор и узел больше не являются текущим процессором и узлом. *

5 голосов
/ 29 января 2009

Вам нужно сделать что-то вроде:

  • Вызовите sched_getaffinity и определите биты процессора
  • Перебираем процессоры, делая sched_setaffinity для каждого (Я не уверен, что после sched_setaffinity вы гарантированно будете на процессоре, или надо явно уступить?)
  • Выполнение CPUID (инструкция asm) ... есть способ получить уникальный идентификатор для каждого ядра из одного из его выходов (см. Документы Intel ). Я смутно помню, что это «APIC ID».
  • Построить таблицу (std :: map?) Из идентификаторов APIC к номеру ЦП, маске сходства или чему-то еще.
  • Если вы сделали это в своем основном потоке, не забудьте вернуть sched_setaffinity ко всем CPUS!

Теперь вы можете снова использовать CPUID, когда вам нужно, и посмотреть, на каком ядре вы находитесь.

Но я бы спросил, зачем тебе это делать; обычно вы хотите взять управление через sched_setaffinity вместо того, чтобы выяснить, на каком ядре вы находитесь (и даже это довольно редкая вещь, которую нужно / нужно). (Вот почему я не знаю решающей детали того, что именно нужно извлечь из CPUID, извините!)

Обновление: только что узнал о sched_getcpu из ответа litb здесь. Намного лучше! (хотя мой Debian / etch libc слишком стар, чтобы иметь его).

2 голосов
/ 29 января 2009

Я ничего не знаю, чтобы получить ваш текущий идентификатор ядра. При переносе задач / процессов на уровне ядра вам не будет гарантировано, что он будет оставаться постоянным в течение любого промежутка времени, если вы не работали в какой-либо форме режима реального времени.

Если вы хотите использовать конкретное ядро, вы можете использовать эту функцию sched_setaffinity() или команду taskset для запуска вашей программы. Я полагаю, что для этого нужны повышенные разрешения для работы. В вашей программе вы могли бы затем запустить sched_getaffinity(), чтобы увидеть маску, которая была установлена ​​ранее, и использовать ее как лучшее предположение для ядра, на котором вы выполняете.

0 голосов
/ 06 февраля 2009
sysconf(_SC_NPROCESSORS_ONLN);
...