Предположительно, есть библиотека или простой asm blob, который может получить мне номер текущего процессора, который я выполняю.
Как я могу получить номер ядра процессора из пользовательского приложения (Linux, C)?
Ответ 1
Используйте sched_getcpu
, чтобы определить процессор, на котором работает вызывающий поток. См. man getcpu
(системный вызов) и man sched_getcpu
(обертка библиотеки). Однако обратите внимание на то, что он говорит:
Информация, размещенная в CPU, гарантируется только во время вызова: если привязка процессора не была исправлена с использованием sched_setaffinity (2), ядро может в любой момент изменить процессор. (Обычно этого не происходит, потому что планировщик пытается свести к минимуму перемещения между процессорами, чтобы сохранить кеши горячие, но это возможно.) Вызывающий должен быть готов обработать ситуацию, когда cpu и node больше не являются текущим CPU и node.
Ответ 2
Вам нужно сделать что-то вроде:
- Вызовите sched_getaffinity и определите бит CPU
- Итерации по ЦП, делая sched_setaffinity для каждого (Я не уверен, что после sched_setaffinity вы гарантированно окажетесь на процессоре или нужно явно дать?)
- Выполнить CPUID (инструкция asm)... есть способ получить уникальный идентификатор для каждого ядра из одного из его выходов (см. Intel docs). Я смутно напоминаю об этом "APIC ID".
- Создайте таблицу (std:: map?) из идентификаторов APIC на номер CPU или маску сродства или что-то в этом роде.
- Если вы сделали это в своем основном потоке, не забудьте установить sched_setaffinity на все CPUS!
Теперь вы можете снова использовать CPUID всякий раз, когда вам нужно, и посмотреть, на каком ядре вы находитесь.
Но я бы спросил, зачем вам это нужно; обычно вы хотите взять контроль через sched_setaffinity, а не узнавать, к какому ядру вы подключаетесь (и даже это довольно редкая вещь, которая нужна/нужна). (Вот почему я не знаю критических деталей того, что вытаскивать из CPUID точно, извините!)
Обновление: только что узнал о sched_getcpu из litb-ответа здесь. Намного лучше! (мой Debian/etch libc слишком стар, чтобы иметь его, хотя).
Ответ 3
Я ничего не знаю, чтобы получить ваш текущий идентификатор ядра. С миграцией задач/процессов на уровне ядра вам не гарантируется, что он останется постоянным в течение какого-то времени, если только вы не работаете в режиме реального времени.
Если вы хотите находиться на определенном ядре, вы можете использовать эту функцию sched_setaffinity()
или команду taskset
для запуска вашей программы. Я считаю, что для этого нужны повышенные права на работу. В вашей программе вы могли бы запустить sched_getaffinity()
, чтобы увидеть маску, которая была установлена ранее, и использовать ее как лучшее предположение в ядре, на котором вы выполняете.
Ответ 4
sysconf(_SC_NPROCESSORS_ONLN);