GetLogicalProcessorInformation 関数 (sysinfoapi.h)

論理プロセッサと関連するハードウェアに関する情報を取得します。

論理プロセッサと関連するハードウェア (プロセッサ グループを含む) に関する情報を取得するには、 GetLogicalProcessorInformationEx 関数を使用します。

構文

BOOL GetLogicalProcessorInformation(
  [out]     PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
  [in, out] PDWORD                                ReturnedLength
);

パラメーター

[out] Buffer

SYSTEM_LOGICAL_PROCESSOR_INFORMATION構造体の配列を受け取るバッファーへのポインター。 関数が失敗した場合、このバッファーの内容は未定義です。

[in, out] ReturnedLength

入力時に、 Buffer が指すバッファーの長さをバイト単位で指定します。 バッファーがすべてのデータを格納するのに十分な大きさの場合、この関数は成功し 、ReturnLength は返されるバイト数に設定されます。 バッファーがすべてのデータを格納するのに十分な大きさでない場合、関数は失敗し、 GetLastError はERROR_INSUFFICIENT_BUFFERを返し、 ReturnLength はすべてのデータを格納するために必要なバッファー長に設定されます。 関数がERROR_INSUFFICIENT_BUFFER以外のエラーで失敗した場合、 ReturnLength の値は未定義です。

戻り値

関数が成功した場合、戻り値は TRUE で、少なくとも 1 つの SYSTEM_LOGICAL_PROCESSOR_INFORMATION 構造体が出力バッファーに書き込まれます。

関数が失敗した場合、戻り値は FALSE になります。 詳細なエラー情報を得るには、GetLastError を呼び出します。

解説

GetLogicalProcessorInformation を使用すると、システム内の論理プロセッサ間の関係に関する次の情報を取得できます。

  • NUMA ノードの一部である論理プロセッサ。
  • リソースを共有する論理プロセッサ。 この種類のリソース共有の例としては、ハイパースレッディング シナリオがあります。
アプリケーションでは、この情報を使用して、プラットフォームのハードウェア プロパティを最大限に活用したり、ライセンス目的で論理プロセッサと物理プロセッサの数を決定したりするために、スレッドとプロセスをアフィニティするときに使用できます。

バッファーで返される 各SYSTEM_LOGICAL_PROCESSOR_INFORMATION 構造体には、次のものが含まれます。

  • 論理プロセッサ アフィニティ マスク。構造体内の情報が適用される論理プロセッサを示します。
  • マスク内の論理プロセッサ間の関係を示す、 LOGICAL_PROCESSOR_RELATIONSHIP型の論理プロセッサ マスク。 この関数を呼び出すアプリケーションは、将来、追加のインジケーター値を処理するために準備する必要があります。
バッファーで構造体が返される順序は、この関数の呼び出しの間で変わる可能性があることに注意してください。

SYSTEM_LOGICAL_PROCESSOR_INFORMATION構造のサイズは、プロセッサ アーキテクチャと Windows のバージョンによって異なります。 このため、アプリケーションは最初にこの関数を呼び出して必要なバッファー サイズを取得してから、バッファーのメモリを動的に割り当てる必要があります。

64 を超える論理プロセッサを持つシステムでは、 GetLogicalProcessorInformation 関数は、呼び出し元のスレッドが現在割り当てられている プロセッサ グループ 内のプロセッサに関する論理プロセッサ情報を取得します。 GetLogicalProcessorInformationEx 関数を使用して、システム上のすべてのプロセッサ グループ内のプロセッサに関する情報を取得します。

注意

TBD Release Iron 以降では、この関数やその他の NUMA 関数の動作が変更され、64 個のプロセッサを含むノードを持つシステムをより適切にサポートするようになりました。 この API の古い動作の有効化に関する情報など、この変更の詳細については、「 NUMA サポート」を参照してください。

TBD リリース 鉄から始まる動作

RelationNumaNode のリレーションシップ構造には、呼び出し元スレッドのグループ内のノードのアフィニティのアフィニティ マスクが含まれています。

次の C++ の例では 、GetLogicalProcessorInformation 関数を使用して、現在のシステム上のプロセッサに関する情報を表示します。 GetLogicalProcessorInformation はすべてのシステムに存在するわけではないため、この例では、GetLogicalProcessorInformation を直接呼び出す代わりに GetProcAddress 関数を使用します。

次の使用例は、アクティブなプロセッサ コアの数を報告します。 この例では、この情報をサポートするシステム上の NUMA ノード、物理パッケージ、キャッシュの数も報告します。 詳細については、SYSTEM_LOGICAL_PROCESSOR_INFORMATION構造体の Relationship メンバーの説明を参照してください。 Windows Server 2003、Windows XP Professional x64 Edition、および Windows XP SP3: この例では、アクティブなプロセッサ コアの数ではなく、物理プロセッサの数を報告します。


#include <windows.h>
#include <malloc.h>    
#include <stdio.h>
#include <tchar.h>

typedef BOOL (WINAPI *LPFN_GLPI)(
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, 
    PDWORD);


// Helper function to count set bits in the processor mask.
DWORD CountSetBits(ULONG_PTR bitMask)
{
    DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
    DWORD bitSetCount = 0;
    ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;    
    DWORD i;
    
    for (i = 0; i <= LSHIFT; ++i)
    {
        bitSetCount += ((bitMask & bitTest)?1:0);
        bitTest/=2;
    }

    return bitSetCount;
}

int _cdecl _tmain ()
{
    LPFN_GLPI glpi;
    BOOL done = FALSE;
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
    DWORD returnLength = 0;
    DWORD logicalProcessorCount = 0;
    DWORD numaNodeCount = 0;
    DWORD processorCoreCount = 0;
    DWORD processorL1CacheCount = 0;
    DWORD processorL2CacheCount = 0;
    DWORD processorL3CacheCount = 0;
    DWORD processorPackageCount = 0;
    DWORD byteOffset = 0;
    PCACHE_DESCRIPTOR Cache;

    glpi = (LPFN_GLPI) GetProcAddress(
                            GetModuleHandle(TEXT("kernel32")),
                            "GetLogicalProcessorInformation");
    if (NULL == glpi) 
    {
        _tprintf(TEXT("\nGetLogicalProcessorInformation is not supported.\n"));
        return (1);
    }

    while (!done)
    {
        DWORD rc = glpi(buffer, &returnLength);

        if (FALSE == rc) 
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
            {
                if (buffer) 
                    free(buffer);

                buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(
                        returnLength);

                if (NULL == buffer) 
                {
                    _tprintf(TEXT("\nError: Allocation failure\n"));
                    return (2);
                }
            } 
            else 
            {
                _tprintf(TEXT("\nError %d\n"), GetLastError());
                return (3);
            }
        } 
        else
        {
            done = TRUE;
        }
    }

    ptr = buffer;

    while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) 
    {
        switch (ptr->Relationship) 
        {
        case RelationNumaNode:
            // Non-NUMA systems report a single record of this type.
            numaNodeCount++;
            break;

        case RelationProcessorCore:
            processorCoreCount++;

            // A hyperthreaded core supplies more than one logical processor.
            logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
            break;

        case RelationCache:
            // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache. 
            Cache = &ptr->Cache;
            if (Cache->Level == 1)
            {
                processorL1CacheCount++;
            }
            else if (Cache->Level == 2)
            {
                processorL2CacheCount++;
            }
            else if (Cache->Level == 3)
            {
                processorL3CacheCount++;
            }
            break;

        case RelationProcessorPackage:
            // Logical processors share a physical package.
            processorPackageCount++;
            break;

        default:
            _tprintf(TEXT("\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\n"));
            break;
        }
        byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
        ptr++;
    }

    _tprintf(TEXT("\nGetLogicalProcessorInformation results:\n"));
    _tprintf(TEXT("Number of NUMA nodes: %d\n"), 
             numaNodeCount);
    _tprintf(TEXT("Number of physical processor packages: %d\n"), 
             processorPackageCount);
    _tprintf(TEXT("Number of processor cores: %d\n"), 
             processorCoreCount);
    _tprintf(TEXT("Number of logical processors: %d\n"), 
             logicalProcessorCount);
    _tprintf(TEXT("Number of processor L1/L2/L3 caches: %d/%d/%d\n"), 
             processorL1CacheCount,
             processorL2CacheCount,
             processorL3CacheCount);
    
    free(buffer);

    return 0;
}


要件

要件
サポートされている最小のクライアント Windows Vista、Windows XP Professional x64 Edition、SP3 搭載 Windows XP [デスクトップ アプリ |UWP アプリ]
サポートされている最小のサーバー Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ]
対象プラットフォーム Windows
ヘッダー sysinfoapi.h
Library Kernel32.lib
[DLL] Kernel32.dll

関連項目

GetLogicalProcessorInformationEx

LOGICAL_PROCESSOR_RELATIONSHIP

プロセス関数とスレッド関数

SYSTEM_LOGICAL_PROCESSOR_INFORMATION