Есть ли способ определить, сколько ядер у машины от C / C ++ независимо от платформы? Если такого не существует, как насчет определения его для каждой платформы (Windows / * nix / Mac)?
Если вы хотите использовать его, выясните, сколько потоков нужно запустить, используйте NUMBER_OF_PROCESSORS в качестве основного показателя. Я оставляю вам в качестве упражнения, почему это намного лучше (если люди будут использовать его чаще), чем использование аппаратных ядер. Сколько ядер принадлежит вашей программе - экологическая проблема!
Лотар
Обратите внимание, что std::thread::hardware_concurrencyвозвращает количество физических ядер ЦП, но nprocв Linux отображается только количество ядер ЦП, на которых может выполняться текущий процесс, которыми можно управлять sched_setaffinity. Я не нашел способа получить это вместо стандартного C ++: см., Например, в Python: stackoverflow.com/questions/1006289/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Ответы:
706
C ++ 11
#include<thread>//may return 0 when not able to detectconstauto processor_count = std::thread::hardware_concurrency();
В C ++ до C ++ 11 нет переносимого способа. Вместо этого вам нужно использовать один или несколько из следующих методов (защищенных соответствующими #ifdefстроками):
Linux, Solaris, AIX и Mac OS X> = 10,4 (т. Е. Tiger и выше)
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
FreeBSD, MacOS X, NetBSD, OpenBSD и т. Д.
int mib[4];int numCPU;
std::size_t len =sizeof(numCPU);/* set the mib for hw.ncpu */
mib[0]= CTL_HW;
mib[1]= HW_AVAILCPU;// alternatively, try HW_NCPU;/* get the number of CPUs from the system */
sysctl(mib,2,&numCPU,&len, NULL,0);if(numCPU <1){
mib[1]= HW_NCPU;
sysctl(mib,2,&numCPU,&len, NULL,0);if(numCPU <1)
numCPU =1;}
HPUX
int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);
IRIX
int numCPU = sysconf(_SC_NPROC_ONLN);
Objective-C (Mac OS X> = 10,5 или iOS)
NSUInteger a =[[NSProcessInfo processInfo] processorCount];NSUInteger b =[[NSProcessInfo processInfo] activeProcessorCount];
@mcandre: это оставлено в качестве упражнения для читателя. Если бы я реализовывал, я бы, вероятно, использовал бы подход политики шаблона, где политика была определена в директивах препроцессора. Или ... вы можете использовать boost thread :: hardware_concurrency ().
paxos1977
3
В качестве пояснения решение Win32 возвращает общее количество ядер (что было запрошено), а не общее количество физических процессоров.
Eric
1
Способ Linux / Solaris / AIX также работает на FreeBSD и существует по крайней мере с 2006 года. Кроме того, он вернет ЦП в оперативный режим, если система способна отключать некоторые из них, они могут не учитываться. Вызов sysconf с "_SC_NPROCESSORS_CONF" вернет общее количество настроенных процессоров.
Крис С
3
Несколько вещей, о которых нужно знать. HW_NCPUустарела в OS X. В Windows GetSystemInfoполезна, только если в вашей системе 32 логических процессора или меньше, используйте GetLogicalProcessorInformationдля систем, в которых более 32 логических процессоров.
1
@Trejkaz, документация ясно говорит «логический» - который всегда учитывает ядра HT, слово «физический» всегда относится к ядрам, сообщаемым BIOS / UEFI, поскольку ядра также могут эмулироваться / виртуализироваться. Вы можете различать ядра HT / non-HT с помощью таких функций, как , например, GetLogicalProcessorInformation . Примечание: HT! = Эмуляция или виртуализация, это большая разница, HT - это, так сказать, аппаратная оптимизация
specializt
202
Эта функциональность является частью стандарта C ++ 11.
В любом случае hardware_concurrency()возвращает количество потоков, которые аппаратное обеспечение способно выполнять одновременно, исходя из количества ядер ЦП и модулей гиперпоточности.
Seconded ... собирался использовать приведенный выше пример кода и некоторые макросы препроцессора для раскрытия одной функции, но тяжелая работа для меня была сделана.
JKP
Для win32 это вызов GetSystemInfo. (Начиная с версии Boost 1.41.0). Собирает ли она всю информацию, чтобы определить, сколько рабочих потоков будет эффективным? Нужно ли учитывать как количество ядер, так и гиперпоточность? неподписанный поток :: hardware_concurrency () {SYSTEM_INFO info = {0}; GetSystemInfo (& информация); return info.dwNumberOfProcessors; }
Джайв Дадсон
Согласно MSDN, GetSystemInfo () возвращает количество «физических процессоров» в dwNumberOfProcessors, но не определяет, что это означает. Документация Boost, кажется, утверждает, что она включает в себя модули гиперпоточности.
потому что это неправильный ответ. От gcc.gnu.org/bugzilla/show_bug.cgi?id=37586 "omp_get_num_procs () будет возвращать только меньшее число, чем количество системных процессоров в сети, если используется env var GOMP_CPU_AFFINITY или если вызывающий процесс и / или поток имеет Сродство процессора ограничено подмножеством процессоров ». Так что, если вы ранее позвоните, например, sched_setaffinityэто не будет работать.
angainor
7
Эта функция возвращает количество процессоров, доступных для вызывающего процесса. Разве это не самый распространенный вариант использования? Помимо некоторых бесполезных целей отчетности, фактическое количество аппаратных ядер ЦП не имеет к вам отношения, если вы не можете использовать их в своем коде.
Macbirdie
@EvanTeran Помимо того, что это было целью вопроса, это, конечно, может быть полезно. Например, с целью установки сходства потоков. Скажем, я хочу запустить 4 потока, привязанных к четырем последним ядрам процессора на моей машине, вместо четырех первых ядер. Кроме того, существуют другие способы распараллеливания кода, кроме OpenMP. Я могу хотеть порождать себя. Они, безусловно, доступны и не ограничены переменными среды OpenMP.
angainor
2
Это возвращает количество логических процессоров, а не ядер (физических процессоров) как таковых.
Михаил Конечны
37
Если у вас есть доступ к языку ассемблера, вы можете использовать инструкцию CPUID для получения всевозможной информации о процессоре. Он переносим между операционными системами, хотя вам нужно будет использовать информацию от производителя, чтобы определить, как найти количество ядер. Вот документ, который описывает, как это сделать на чипах Intel , и на странице 11 этого описания спецификация AMD.
Возможно, он был отвергнут, потому что вопрос помечен как C ++, и этот ответ не относится к системам, использующим C ++ на архитектурах не-x86 (ARM, PPC и т. Д.). Я не говорю, что это хорошая причина для отрицательного ответа, просто возможность.
Ферруччо
3
Один из недостатков этого метода - использование CPUID для обнаружения HyperThreading на процессорах Intel. Я столкнулся с этой проблемой на своем ноутбуке: в то время как процессор, который я вставил в машину, поддерживает HyperThreading (и, конечно, сообщает, что это происходит через CPUID), BIOS не поддерживает. Следовательно, вы не должны пытаться использовать возможности HT просто из чтения CPUID. Поскольку вы не можете запросить BIOS о поддержке HT (ни в коем случае, как я видел), необходимо запросить ОС, чтобы узнать количество логических процессоров.
За исключением того, что это также считает гиперпоточные или другие решения SMT как больше ядер ...
jakobengblom2
13
@Arafangion: гиперпоточность - это не совсем параллельное выполнение, это технология для снижения издержек переключения контекста. Многопоточный процессор может одновременно выполнять только один поток, но он может хранить архитектурное состояние (значения регистров и т. Д.) Двух потоков одновременно. Характеристики производительности сильно отличаются от двух ядер.
Вим Коенен
7
@Wim: Это не совсем правильно. Процессоры с гиперпоточностью обычно имеют несколько ALU и могут отправлять несколько команд за цикл. Если из-за зависимостей данных и остановок не все ALU могут быть заняты одним потоком, эти ALU вместо этого будут использоваться для одновременного выполнения второго аппаратного потока.
Бен Фойгт
11
Обратите внимание, что «число ядер» может быть не особенно полезным числом, вам, возможно, придется уточнить его немного больше. Как вы хотите сосчитать многопоточные процессоры, такие как Intel HT, IBM Power5 и Power6, и наиболее известные из них - Sun Niagara / UltraSparc T1 и T2? Или, что еще интереснее, MIPS 1004k с двумя уровнями аппаратного потока (супервизор и пользовательский уровень) ... Не говоря уже о том, что происходит, когда вы переходите в системы с поддержкой гипервизора, где на оборудовании могут быть десятки процессоров, но ваша конкретная ОС видит только несколько.
Лучшее, на что вы можете надеяться, - это указать количество логических процессоров, которые есть в вашем локальном разделе ОС. Забудьте о том, чтобы увидеть настоящую машину, если вы не являетесь гипервизором. Единственное исключение из этого правила сегодня на земле x86, но конец не виртуальных машин скоро наступит ...
Осторожно: процессоры Hyperthreaded говорят, что их два. Таким образом, вам также необходимо проверить, поддерживает ли процессор технологию Hyperthread.
Обратите внимание, что реализация NumberOfPhysicalCoresIMHO далеко не тривиальна (то есть «использовать GetLogicalProcessorInformationили GetLogicalProcessorInformationEx»). Вместо этого это довольно тонко, если кто-то читает документацию (явно присутствует GetLogicalProcessorInformationи неявно присутствует GetLogicalProcessorInformationEx) в MSDN.
Количество логических процессоров. (Используя GetSystemInfo )
Спасибо! Я искал это из-за того, что GetLogicalProcessorInformationне работал с различными размерами буфера, которые я использовал. Более чем доволен! ^^
KeyWeeUsr
@KeyWeeUsr Благодаря Windows, программирование несколько далеко от тривиального и логического. В то же время я использую немного более обновленную версию C ++ 17, которая также более корректна в соответствии со статическим анализатором PVS-Studio в отношении некоторых size_tприведений. (Хотя msvc ++ не жалуется на W4.)
Матиас
5
Больше на OS X: sysconf(_SC_NPROCESSORS_ONLN)доступно только версии> = 10.5, а не 10.4.
Альтернативой является HW_AVAILCPU/sysctl()код BSD, который доступен в версиях> = 10.2.
Для питона:import multiprocessingprint multiprocessing.cpu_count()
initzero
3
Это было давно, но grepесть -cфлаг для подсчета записей!
Лапшин Дмитрий
3
hwloc (http://www.open-mpi.org/projects/hwloc/) стоит посмотреть. Хотя требуется интеграция другой библиотеки в ваш код, но она может предоставить всю информацию о вашем процессоре (количество ядер, топология и т. Д.)
В Linux это может быть небезопасно для использования, _SC_NPROCESSORS_ONLNпоскольку оно не является частью стандарта POSIX и так много говорится в руководстве sysconf . Так что есть вероятность, что _SC_NPROCESSORS_ONLNможет не присутствовать:
These values also exist, but may not be standard.[...]- _SC_NPROCESSORS_CONF
The number of processors configured.- _SC_NPROCESSORS_ONLN
The number of processors currently online (available).
Простым подходом было бы прочитать /proc/statили /proc/cpuinfoсосчитать их:
#include<unistd.h>#include<stdio.h>int main(void){char str[256];int procCount =-1;// to offset for the first entry
FILE *fp;if((fp = fopen("/proc/stat","r"))){while(fgets(str,sizeof str, fp))if(!memcmp(str,"cpu",3)) procCount++;}if( procCount ==-1){
printf("Unable to get proc count. Defaulting to 2");
procCount=2;}
printf("Proc Count:%d\n", procCount);return0;}
Использование /proc/cpuinfo:
#include<unistd.h>#include<stdio.h>int main(void){char str[256];int procCount =0;
FILE *fp;if((fp = fopen("/proc/cpuinfo","r"))){while(fgets(str,sizeof str, fp))if(!memcmp(str,"processor",9)) procCount++;}if(!procCount ){
printf("Unable to get proc count. Defaulting to 2");
procCount=2;}
printf("Proc Count:%d\n", procCount);return0;}
Тот же подход в оболочке с использованием grep:
grep -c ^processor /proc/cpuinfo
Или
grep -c ^cpu /proc/stat # subtract 1 from the result
Альтернатива OS X: Решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount], доступно только в OS X 10.5.0, в соответствии с документацией. Для более ранних версий OS X используйте функцию Carbon MPProcessors ().
Если вы программист какао, не пугайтесь того факта, что это Carbon. Вам просто нужно добавить платформу Carbon в ваш проект Xcode, и MPProcessors () будет доступен.
В то время как GetSystemInfo () возвращает количество логических процессоров, используйте
GetLogicalProcessorInformationEx ()
для получения количества физических процессоров.
вы также можете использовать WMI в .net, но в этом случае вы зависите от работающей службы wmi и т. д. Иногда она работает локально, но затем перестает работать, когда тот же код выполняется на серверах. Я считаю, что это проблема пространства имен, связанная с «именами», значения которых вы читаете.
std::thread::hardware_concurrency
возвращает количество физических ядер ЦП, ноnproc
в Linux отображается только количество ядер ЦП, на которых может выполняться текущий процесс, которыми можно управлятьsched_setaffinity
. Я не нашел способа получить это вместо стандартного C ++: см., Например, в Python: stackoverflow.com/questions/1006289/…Ответы:
C ++ 11
Ссылка: std :: thread :: hardware_concurrency
В C ++ до C ++ 11 нет переносимого способа. Вместо этого вам нужно использовать один или несколько из следующих методов (защищенных соответствующими
#ifdef
строками):Win32
Linux, Solaris, AIX и Mac OS X> = 10,4 (т. Е. Tiger и выше)
FreeBSD, MacOS X, NetBSD, OpenBSD и т. Д.
HPUX
IRIX
Objective-C (Mac OS X> = 10,5 или iOS)
источник
HW_NCPU
устарела в OS X. В WindowsGetSystemInfo
полезна, только если в вашей системе 32 логических процессора или меньше, используйтеGetLogicalProcessorInformation
для систем, в которых более 32 логических процессоров.Эта функциональность является частью стандарта C ++ 11.
Для более старых компиляторов вы можете использовать библиотеку Boost.Thread .
В любом случае
hardware_concurrency()
возвращает количество потоков, которые аппаратное обеспечение способно выполнять одновременно, исходя из количества ядер ЦП и модулей гиперпоточности.источник
OpenMP поддерживается на многих платформах (включая Visual Studio 2005) и предлагает
функция, которая возвращает количество процессоров / ядер, доступных на момент вызова.
источник
sched_setaffinity
это не будет работать.Если у вас есть доступ к языку ассемблера, вы можете использовать инструкцию CPUID для получения всевозможной информации о процессоре. Он переносим между операционными системами, хотя вам нужно будет использовать информацию от производителя, чтобы определить, как найти количество ядер. Вот документ, который описывает, как это сделать на чипах Intel , и на странице 11 этого описания спецификация AMD.
источник
(Почти) Независимая от платформы функция в c-коде
источник
HW_NCPU
, устарела на OS X источникВ Linux вы можете прочитать файл / proc / cpuinfo и подсчитать количество ядер.
источник
Обратите внимание, что «число ядер» может быть не особенно полезным числом, вам, возможно, придется уточнить его немного больше. Как вы хотите сосчитать многопоточные процессоры, такие как Intel HT, IBM Power5 и Power6, и наиболее известные из них - Sun Niagara / UltraSparc T1 и T2? Или, что еще интереснее, MIPS 1004k с двумя уровнями аппаратного потока (супервизор и пользовательский уровень) ... Не говоря уже о том, что происходит, когда вы переходите в системы с поддержкой гипервизора, где на оборудовании могут быть десятки процессоров, но ваша конкретная ОС видит только несколько.
Лучшее, на что вы можете надеяться, - это указать количество логических процессоров, которые есть в вашем локальном разделе ОС. Забудьте о том, чтобы увидеть настоящую машину, если вы не являетесь гипервизором. Единственное исключение из этого правила сегодня на земле x86, но конец не виртуальных машин скоро наступит ...
источник
Еще один рецепт Windows: используйте общесистемную переменную среды
NUMBER_OF_PROCESSORS
:источник
Вы, вероятно, не сможете получить его независимо от платформы. Windows вы получаете количество процессоров.
Win32 Системная информация
источник
Windows (x64 и Win32) и C ++ 11
Количество групп логических процессоров, разделяющих одно процессорное ядро. (Используя GetLogicalProcessorInformationEx , см. Также GetLogicalProcessorInformation )
Обратите внимание, что реализация
NumberOfPhysicalCores
IMHO далеко не тривиальна (то есть «использоватьGetLogicalProcessorInformation
илиGetLogicalProcessorInformationEx
»). Вместо этого это довольно тонко, если кто-то читает документацию (явно присутствуетGetLogicalProcessorInformation
и неявно присутствуетGetLogicalProcessorInformationEx
) в MSDN.Количество логических процессоров. (Используя GetSystemInfo )
Обратите внимание, что оба метода могут быть легко преобразованы в C / C ++ 98 / C ++ 03.
источник
GetLogicalProcessorInformation
не работал с различными размерами буфера, которые я использовал. Более чем доволен! ^^size_t
приведений. (Хотя msvc ++ не жалуется на W4.)Больше на OS X:
sysconf(_SC_NPROCESSORS_ONLN)
доступно только версии> = 10.5, а не 10.4.Альтернативой является
HW_AVAILCPU/sysctl()
код BSD, который доступен в версиях> = 10.2.источник
Windows Server 2003 и более поздние версии позволяют использовать функцию GetLogicalProcessorInformation
http://msdn.microsoft.com/en-us/library/ms683194.aspx
источник
Не связанный с C ++, но в Linux я обычно делаю:
Удобно для скриптовых языков, таких как bash / perl / python / ruby.
источник
import multiprocessing
print multiprocessing.cpu_count()
grep
есть-c
флаг для подсчета записей!hwloc (http://www.open-mpi.org/projects/hwloc/) стоит посмотреть. Хотя требуется интеграция другой библиотеки в ваш код, но она может предоставить всю информацию о вашем процессоре (количество ядер, топология и т. Д.)
источник
Насколько мне известно, в Linux лучший программный способ - это использовать
или
Они не являются стандартными, но есть в моей справочной странице по Linux.
источник
В Linux это может быть небезопасно для использования,
_SC_NPROCESSORS_ONLN
поскольку оно не является частью стандарта POSIX и так много говорится в руководстве sysconf . Так что есть вероятность, что_SC_NPROCESSORS_ONLN
может не присутствовать:Простым подходом было бы прочитать
/proc/stat
или/proc/cpuinfo
сосчитать их:Использование
/proc/cpuinfo
:Тот же подход в оболочке с использованием grep:
Или
источник
Альтернатива OS X: Решение, описанное ранее на основе [[NSProcessInfo processInfo] processorCount], доступно только в OS X 10.5.0, в соответствии с документацией. Для более ранних версий OS X используйте функцию Carbon MPProcessors ().
Если вы программист какао, не пугайтесь того факта, что это Carbon. Вам просто нужно добавить платформу Carbon в ваш проект Xcode, и MPProcessors () будет доступен.
источник
Для Win32:
В то время как GetSystemInfo () возвращает количество логических процессоров, используйте GetLogicalProcessorInformationEx () для получения количества физических процессоров.
источник
вы также можете использовать WMI в .net, но в этом случае вы зависите от работающей службы wmi и т. д. Иногда она работает локально, но затем перестает работать, когда тот же код выполняется на серверах. Я считаю, что это проблема пространства имен, связанная с «именами», значения которых вы читаете.
источник
В Linux вы можете извлекать dmesg и фильтровать строки, в которых ACPI инициализирует процессоры, что-то вроде:
dmesg | grep 'ACPI: Processor
'Другая возможность - использовать dmidecode для фильтрации информации о процессоре.
источник