質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

8251閲覧

__cpuid()を使って物理コア数を取得したい

NSTK

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/04/02 08:52

###前提・実現したいこと
__cpuid()を使ってCPUの物理コア数を取得したいのですがうまくいきません。
4コアのCPUで下記のソースコードで試したところ8と表示されました。

__cpuid()を使って正しい物理コア数を取得する方法を教えていただけないでしょうか。
また、C++でCPUの物理コア数を取得する方法が他にございましたらそちらも教えて欲しいです。
よろしくお願いします。

###該当のソースコード

C++

1#include <cstdio> 2#include <intrin.h> 3#include <cstring> 4#include <windows.h> 5 6#define NUM_CORE_MASK 0xfc000000 7#define NUM_CORE_OFFSET 26 8 9int main(void) 10{ 11 int data[4]; 12 int num_cores = 0; 13 14 memset(data, 0, sizeof(data)); 15 __cpuid(data,0x0); 16 17 if (data[0] >= 4) { 18 memset(data, 0, sizeof(data)); 19 __cpuid(data, 0x4); 20 21 // eax[26:31]をとりだす 22 num_cores = (data[0] & NUM_CORE_MASK) >> NUM_CORE_OFFSET; 23 num_cores++; 24 } 25 printf("# of cores : %d",num_cores); 26 Sleep(1000); 27 28 return 0; 29}

###補足情報(言語/FW/ツール等のバージョンなど)
OS:Windows7
コンパイル環境:Visual Studio Community 2015
CPU:Intel Core i7-2600

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

StackOverflowに、該当しそうな回答がありました。

現在Windows環境がないため動作確認はできないのですが、cpuidからハイパースレッディングが有効になっているかの情報を取得し、有効であれば論理コア数を2で割る必要があるように思います。

(前略)先に示した方法で、論理コア数が得られました。意図した結果(物理コア数)を得るために、まずハイパースレッディングが使用されているかどうか、またはそれが利用可能かどうかを確認する必要があります。

cpp

1__asm__ __volatile__ ("cpuid " : 2 "=a" (registers[0]), 3 "=b" (registers[1]), 4 "=c" (registers[2]), 5 "=d" (registers[3]) 6 : "a" (1), "c" (0)); 7 8unsigned CPUFeatureSet = registers[3]; 9bool hyperthreading = CPUFeatureSet & (1 << 28);

(中略)ハイパースレッディングが利用可能な場合、論理コア数は物理コア数のちょうど2倍になります。

EAXが1の場合(__cpuidの第2引数function_idに1を渡した場合)、EDX (data[3]) の28ビット目が、ハイパースレッディングの有効・無効を表しているようです。

EAX=1 CPUID feature bits

ビットShort機能
28httHyper-threading

C++で物理コア数を取得するほかの方法としては、Boost Thread Libraryのboost::thread::physical_concurrency()静的メンバ関数を使用するものがあります。

そのWindows環境での実装は、以下のようになっています:

cpp

1// https://github.com/boostorg/thread/blob/49ab2e86197620fc0efd14368037b2b1e41a025e/src/win32/thread.cpp 2 3// Distributed under the Boost Software License, Version 1.0. (See 4// accompanying file LICENSE_1_0.txt or copy at 5// http://www.boost.org/LICENSE_1_0.txt) 6// (C) Copyright 2007 Anthony Williams 7// (C) Copyright 2007 David Deakins 8// (C) Copyright 2011-2013 Vicente J. Botet Escriba 9 10 unsigned thread::physical_concurrency() BOOST_NOEXCEPT 11 { 12 // a bit too strict: Windows XP with SP3 would be sufficient 13 // Windows XP SP3より古いと実装は難しい 14#if BOOST_PLAT_WINDOWS_RUNTIME \ 15 || ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) \ 16 || ( ( defined(__MINGW32__) && !defined(__MINGW64__) ) && _WIN32_WINNT < 0x0600) 17 return 0; 18#else 19 unsigned cores = 0; 20 DWORD size = 0; 21 22 GetLogicalProcessorInformation(NULL, &size); 23 if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) 24 return 0; 25 26 std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size); 27 if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE) 28 return 0; 29 30 const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); 31 32 for (size_t i = 0; i < Elements; ++i) { 33 if (buffer[i].Relationship == RelationProcessorCore) 34 ++cores; 35 } 36 return cores; 37#endif

投稿2017/04/05 07:33

編集2017/04/05 09:54
faithandbrave

総合スコア132

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NSTK

2017/04/07 15:19

返信が遅れてしまい申し訳ございません。回答ありがとうございます。 __cpuid()から一発で物理コアを取得することは難しいみたいですね。。。 boostのライブラリは無いのですが関数の内容自体は前の方のリンク先と同じみたいですね。 色々と調べて頂きありがとうございました。
guest

0

Windows(XP SP3 以降)で使える方法として、Win APIにGetLogicalProcessorInformationという関数があります。
それを使ってしまってはいかがでしょうか?

MSDN : GetLogicalProcessorInformation function

投稿2017/04/02 13:48

mitama_rs

総合スコア165

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NSTK

2017/04/02 14:39

ありがとうございます。 上記関数でちゃんと物理コア数が取得できました。 やはり__cpuid()から取得するのは難しいのでしょうか...
guest

0

cpuidについてはよく分かってないので、外してるかもですが。Intel Core i7-2600 は4コアだと思いますが・・・ハイパー・スレッドならば8です。・・・たぶんこちらの情報でしょう

投稿2017/04/02 09:53

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問