Как вызвать cpuid в Linux?

При написании нового кода для Windows я наткнулся на _cpuinfo() из Windows API. Поскольку я в основном имею дело со средой Linux (GCC), я хочу иметь доступ к CPUInfo.

Я пробовал следующее:

#include <iostream>

int main()
{
  int a, b;

  for (a = 0; a < 5; a++)
  {
    __asm ( "mov %1, %%eax; "            // a into eax
          "cpuid;"
          "mov %%eax, %0;"             // eax into b
          :"=r"(b)                     // output
          :"r"(a)                      // input
          :"%eax","%ebx","%ecx","%edx" // clobbered register
         );
    std::cout << "The code " << a << " gives " << b << std::endl;
  }

  return 0;
}

Это использование сборки, но я не хочу изобретать велосипед. Есть ли другой способ реализовать CPUInfo без сборки?

Ошибки компилятора:

lewis@lewis-desktop:~/Desktop/prog$ g++ -Wall CPUInfo.cpp
CPUInfo.cpp: In function ‘int main()’:
CPUInfo.cpp:10:22: error: expected ‘)’ before ‘;’ token
CPUInfo.cpp:10:23: error: expected primary-expression before ‘)’ token
CPUInfo.cpp:10:23: error: expected ‘;’ before ‘)’ token
CPUInfo.cpp:8:8: warning: unused variable ‘b’ [-Wunused-variable]
CPUInfo.cpp:12:8: error: expected ‘}’ at end of input

person TheBlueCat    schedule 10.01.2013    source источник
comment
Итак, я думаю, это g++. А х86? Тебе следует сказать. В чем вопрос в любом случае? Вы рассказали нам, что делаете, и показали код. Но нет вопросов.   -  person David Heffernan    schedule 11.01.2013
comment
@JerryCoffin Я использую Linux (так как это будет раздел Linux для определения процессора компьютера, выполняющего код). У меня уже есть версия/раздел для Windows с функцией _cpuinfo() из Win API. Это моя точка зрения.   -  person TheBlueCat    schedule 11.01.2013
comment
@DavidHeffernan Смотрите мой обновленный пост, я забыл добавить ошибки компилятора.   -  person TheBlueCat    schedule 11.01.2013
comment
Я отредактировал вопрос, чтобы отразить (что я думаю) предполагаемый вопрос. Не стесняйтесь откатить его назад, если я ошибаюсь.   -  person Mysticial    schedule 11.01.2013
comment
опять же, за подходящий вопрос проголосовали против, даже если нет четкого ответа (его нет).   -  person TheBlueCat    schedule 11.01.2013
comment
Если мое редактирование верно, дайте мне знать, и я опубликую ответ.   -  person Mysticial    schedule 11.01.2013
comment
@Mysticial Я знаю, как это реализовать для gcc/linux. Я получаю ошибки компиляции, от которых я не знаю, как избавиться, поэтому создайте чертову сборку.   -  person TheBlueCat    schedule 11.01.2013
comment
Я не знаю, почему вы жалуетесь на отрицательный голос. Теперь я не минусовал, и я вижу, что это было удалено. Но в исходном вопросе опущены подробности о компиляторах, не предоставлены сообщения об ошибках и не задан вопрос. Итак, кто-то проголосовал за вас. Этого следовало ожидать. Не вините downvoter. Исправьте вопрос. Тогда вы получите голоса.   -  person David Heffernan    schedule 11.01.2013
comment
@DavidHeffernan дал хороший ответ; в зависимости от того, что вы хотите, может быть проще прочитать данные из /proc/cpuinfo.   -  person Jerry Coffin    schedule 11.01.2013
comment
Я откатила вопрос назад. Пожалуйста, не меняйте его, как вы. Если вы хотите добавить свой собственный ответ, сделайте это. Но если убрать из вопроса все ошибки, то ответы выглядят глупо.   -  person David Heffernan    schedule 11.01.2013
comment
@DavidHeffernan Я не согласен. В заголовке говорится: «Как мне вызвать «cpuid» в Linux?». Ошибки компилятора, где опечатка из-за переключения ветвей git, когда я тестировал этот код; т.е. не в производственном коде. Ответ не относится к ошибкам компилятора, тогда как он относится к тому, как мне вызвать cpuinfo из cpuid.h. Извините, я собираюсь отредактировать свой вопрос для ясности.   -  person TheBlueCat    schedule 11.01.2013
comment
Ваше последнее редактирование отличается от того, которое я отменил. Этот лучше. Но я бы все же предпочел увидеть исходный код с ошибкой компилятора, потому что один из ответов теперь выглядит очень странно. Это не вина @user. Просто ответили, что было на тот момент. Так что я скорее увижу, как ваше редактирование добавляется к оригиналу.   -  person David Heffernan    schedule 11.01.2013
comment
@DavidHeffernan Я добавлю ошибки компилятора с примечанием.   -  person TheBlueCat    schedule 11.01.2013
comment
Ошибки компиляции обязательно должны соответствовать коду в вопросе с бродячим ; но, может быть, не стоит больше беспокоиться. Я подозреваю, что раздражаю вас сейчас! ;-)   -  person David Heffernan    schedule 11.01.2013
comment
@DavidHeffernan Я думал о том же. Пост будет загроможден кодом. Я думаю, что мой ассемблерный подход довольно новый, он, несомненно, повысит ценность потока. сообщение пользователя хорошо отвечает на опечатку, не говоря уже о примерах кода; хотя в настоящее время в нижнем колонтитуле. Я чувствую , что читатель может собрать его воедино .   -  person TheBlueCat    schedule 11.01.2013
comment
@TheBlueCat Это не так уж и ново, сегодня я видел этот ответ не менее чем на 6 похожих вопросов, когда искал достойный пример с использованием встроенного C / C ++. Вместо специальных ответов на встроенные сборки разных людей :-)   -  person UpAndAdam    schedule 12.03.2014


Ответы (2)


Поскольку вы компилируете с помощью GCC, вы можете включить cpuid.h, который объявляет эти функции:

/* Return highest supported input value for cpuid instruction.  ext can
   be either 0x0 or 0x8000000 to return highest supported value for
   basic or extended cpuid information.  Function returns 0 if cpuid
   is not supported or whatever cpuid returns in eax register.  If sig
   pointer is non-null, then first four bytes of the signature
   (as found in ebx register) are returned in location pointed by sig.  */
unsigned int __get_cpuid_max (unsigned int __ext, unsigned int *__sig)

/* Return cpuid data for requested cpuid level, as found in returned
   eax, ebx, ecx and edx registers.  The function checks if cpuid is
   supported and returns 1 for valid cpuid information or 0 for
   unsupported cpuid level.  All pointers are required to be non-null.  */
int __get_cpuid (unsigned int __level,
    unsigned int *__eax, unsigned int *__ebx,
    unsigned int *__ecx, unsigned int *__edx)

Вам не нужно и не следует повторно реализовывать эту функциональность.

person David Heffernan    schedule 10.01.2013
comment
+1 Не знал, что такой заголовок существует. Я всегда делал это с небольшим количеством встроенной сборки. - person Mysticial; 11.01.2013
comment
Конечно. Мне все равно удалось собрать эту часть. Тем не менее, почему бы мне не реализовать это повторно? Кроме экономии времени? - person TheBlueCat; 11.01.2013
comment
@Mysticial Вот где мне пригодится мое полное незнание GCC и Linux. Пришлось гуглить ответ! - person David Heffernan; 11.01.2013
comment
Основное правило разработки заключается в повторном использовании, а не повторной реализации. Вы сами пишете printf? Или свой собственный strcmp? Вы сами пишете std::string? - person David Heffernan; 11.01.2013
comment
@DavidHeffernan Еще одна причина, по которой невежество подпитывает новые идеи... ахаха - person Mysticial; 11.01.2013
comment
Можете ли вы предоставить/включить пример использования? И, возможно, добавьте типы возвращаемых значений: -P - person UpAndAdam; 12.03.2014
comment
@UpAndAdam Справедливый комментарий, особенно. возвращаемые значения. Я добавил это. Я также включил комментарии из заголовочного файла, в которых описано, как их вызывать. У меня нет под рукой подходящего компилятора, поэтому не хочу пробовать пример использования и ошибаться. - person David Heffernan; 12.03.2014
comment
Без проблем, очень признателен! Я также видел эти комментарии в заголовочном файле и надеялся, что они имеют немного больше смысла для кого-то еще :-p Мне просто нужно продолжить читать еще немного - person UpAndAdam; 12.03.2014
comment
@UpAndAdam Я думаю, вам нужно прочитать документы Intel для CPUID, чтобы понять их. - person David Heffernan; 12.03.2014
comment
Я пытался, конечно, их просто много, и каждый читается немного иначе, чем предыдущий :-P Еще раз спасибо за помощь! - person UpAndAdam; 12.03.2014
comment
Есть только один официальный документ Intel. - person David Heffernan; 12.03.2014
comment
привет для уровня 1, eax=1 мой регистр ebx продолжает выводить случайные значения, я могу как-нибудь проверить, актуален ли регистр для уровня или нет. - person itsnevertoobadtoaskforhelp; 11.08.2016

for (a =0; a < 5; ++a;)

Там должно быть только две точки с запятой. У вас есть три.

Это базовый синтаксис C/C++; CPUID — отвлекающий маневр.

person user9876    schedule 10.01.2013
comment
опечатка. Я исправил его перед публикацией, по какой-то причине он вернулся туда. Я поменял ветки на Git, наверное причина в этом. Но да, я знаю этот «базовый синтаксис». - person TheBlueCat; 11.01.2013
comment
Но ошибки, которые вы разместили, вызваны этой опечаткой. Если вы исправили это, но проблемы все еще возникают, обновите список ошибок. - person user9876; 11.01.2013