528

プラットフォームに依存しない方法で、マシンが C/C++ から持っているコアの数を判断する方法はありますか? そのようなものが存在しない場合、プラットフォーム (Windows/*nix/Mac) ごとに決定するのはどうですか?

4

20 に答える 20

796

C++11

#include <thread>

//may return 0 when not able to detect
const auto processor_count = std::thread::hardware_concurrency();

参照: std::thread::hardware_concurrency


C++11 より前の C++ では、移植可能な方法はありません。代わりに、次のメソッドの 1 つ以上を使用する必要があります (適切な#ifdef行で保護されています)。

  • Win32

    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    int numCPU = sysinfo.dwNumberOfProcessors;
    
  • 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);
    
  • イリックス

    int numCPU = sysconf(_SC_NPROC_ONLN);
    
  • Objective-C (Mac OS X >=10.5 または iOS)

    NSUInteger a = [[NSProcessInfo processInfo] processorCount];
    NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
    
于 2008-09-29T22:14:07.143 に答える
217

この機能は C++11 標準の一部です。

#include <thread>

unsigned int nthreads = std::thread::hardware_concurrency();

古いコンパイラの場合は、Boost.Threadライブラリを使用できます。

#include <boost/thread.hpp>

unsigned int nthreads = boost::thread::hardware_concurrency();

どちらの場合も、hardware_concurrency()CPU コアとハイパースレッディング ユニットの数に基づいて、ハードウェアが同時に実行できるスレッドの数を返します。

于 2008-09-29T19:58:46.593 に答える
65

OpenMPは多くのプラットフォーム (Visual Studio 2005 を含む) でサポートされており、

int omp_get_num_procs();

呼び出し時に使用可能なプロセッサ/コアの数を返す関数。

于 2008-10-13T10:28:30.553 に答える
39

アセンブリ言語にアクセスできる場合は、CPUID命令を使用して、CPUに関するあらゆる種類の情報を取得できます。オペレーティングシステム間で移植可能ですが、コアの数を見つける方法を決定するには、メーカー固有の情報を使用する必要があります。これはIntelチップでそれを行う方法を説明するドキュメントであり、このドキュメントの11ページはAMD仕様を説明しています。

于 2008-09-29T20:49:44.913 に答える
37

(ほぼ) C コードのプラットフォームに依存しない関数

#ifdef _WIN32
#include <windows.h>
#elif MACOS
#include <sys/param.h>
#include <sys/sysctl.h>
#else
#include <unistd.h>
#endif

int getNumCores() {
#ifdef WIN32
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    return sysinfo.dwNumberOfProcessors;
#elif MACOS
    int nm[2];
    size_t len = 4;
    uint32_t count;

    nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
    sysctl(nm, 2, &count, &len, NULL, 0);

    if(count < 1) {
        nm[1] = HW_NCPU;
        sysctl(nm, 2, &count, &len, NULL, 0);
        if(count < 1) { count = 1; }
    }
    return count;
#else
    return sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
于 2010-06-09T13:48:51.240 に答える
17

Linux では、/proc/cpuinfo ファイルを読み取ってコアをカウントできます。

于 2008-09-29T19:55:25.340 に答える
11

「コア数」は特に有用な数値ではない可能性があることに注意してください。もう少し修飾する必要があるかもしれません。Intel HT、IBM Power5 および Power6、そして最も有名な Sun の Niagara/UltraSparc T1 および T2 などのマルチスレッド CPU をどのようにカウントしますか? または、さらに興味深いのは、2 レベルのハードウェア スレッド (スーパーバイザー レベルとユーザー レベル) を備えた MIPS 1004k です。いくつかしか見えません。

期待できる最善の方法は、ローカル OS パーティションにある論理処理ユニットの数を伝えることです。ハイパーバイザーでない限り、実際のマシンを見ることは忘れてください。今日のこのルールの唯一の例外は x86 の世界ですが、非仮想マシンの終焉は急速に近づいています...

于 2008-10-12T19:12:17.533 に答える
8

もう 1 つの Windows レシピ: システム全体の環境変数を使用しますNUMBER_OF_PROCESSORS

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
于 2008-10-13T15:09:15.887 に答える
7

おそらく、プラットフォームに依存しない方法で取得することはできません。Windows では、プロセッサの数を取得します。

Win32 システム情報

于 2008-09-29T19:55:28.770 に答える
5

C++ とは関係ありませんが、Linux では通常次のようにします。

grep processor /proc/cpuinfo | wc -l

bash/perl/python/ruby などのスクリプト言語に便利です。

于 2011-03-21T19:05:24.383 に答える
5

OS X の詳細: sysconf(_SC_NPROCESSORS_ONLN)10.4 ではなく、10.5 以降のバージョンでのみ利用できます。

代替手段は、HW_AVAILCPU/sysctl()バージョン >= 10.2 で利用可能な BSD コードです。

于 2012-09-02T20:13:00.977 に答える
4

Windows Server 2003 以降では、GetLogicalProcessorInformation 関数を利用できます

http://msdn.microsoft.com/en-us/library/ms683194.aspx

于 2008-09-29T19:54:54.903 に答える
3

hwloc(http://www.open-mpi.org/projects/hwloc/)は一見の価値があります。コードに別のライブラリを統合する必要がありますが、プロセッサに関するすべての情報(コアの数、トポロジなど)を提供できます。

于 2011-07-19T19:11:16.950 に答える
3

Linuxでは、私が知る限り、プログラムによる最良の方法は使用することです

sysconf(_SC_NPROCESSORS_CONF)

また

sysconf(_SC_NPROCESSORS_ONLN)

これらは標準ではありませんが、私の Linux の man ページにあります。

于 2008-09-29T19:58:52.787 に答える
3

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);
return 0;
}

使用/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);
return 0;
}

grep を使用したシェルでの同じアプローチ:

grep -c ^processor /proc/cpuinfo

または

grep -c ^cpu /proc/stat # subtract 1 from the result
于 2014-06-09T19:53:38.103 に答える
2

OS Xの代替:ドキュメントによると、[[NSProcessInfoprocessInfo]processorCount]に基づく前述のソリューションはOSX10.5.0でのみ利用可能です。以前のバージョンのOSXの場合は、Carbon関数MPProcessors()を使用します。

あなたがCocoaプログラマーなら、これがCarbonであるという事実に驚かないでください。XcodeプロジェクトにCarbonフレームワークを追加するだけで、MPProcessors()が使用可能になります。

于 2009-07-12T20:00:28.150 に答える
-2

.netでもWMIを使用できますが、実行中のwmiサービスなどに依存しています。ローカルで機能することもありますが、同じコードがサーバーで実行されると失敗します。これは、値を読んでいる「名前」に関連する名前空間の問題だと思います。

于 2008-12-21T19:02:21.620 に答える