プログラムでキャッシュラインサイズを取得しますか?


177

すべてのプラットフォームを歓迎します。回答のプラットフォームを指定してください。

同様の質問:C ++でプログラムでCPUキャッシュページサイズを取得する方法?


8
:FWIW、C ++ 17は、こののコンパイル時の近似値を提供しますstackoverflow.com/questions/39680206/...
GManNickG

C / C ++は別として、そのような情報を取得するためにアセンブリを使用してもかまわない場合は、SDL2のSDL_GetCPUCacheLineSize関数のソースコードを調べ(negamartinの回答から情報を展開)cpuid macro、それぞれにアセンブリソースコードがあるかどうかを確認できます。プロセッサモデルの。あなたは見てみることができimgur.com/a/KP57m6s、または直接ソースを自分で覗い。
haxpor

回答:


186

Linux(かなり最近のカーネルを使用)では、/ sysからこの情報を取得できます。

/sys/devices/system/cpu/cpu0/cache/

このディレクトリには、キャッシュのレベルごとにサブディレクトリがあります。これらの各ディレクトリには、次のファイルが含まれています。

coherency_line_size
level
number_of_sets
physical_line_partition
shared_cpu_list
shared_cpu_map
size
type
ways_of_associativity

これにより、キャッシュラインサイズ(coherency_line_size)やCPUがこのキャッシュを共有しているものなど、知りたいと思うキャッシュに関する詳細情報が得られます。これは、共有データを使用してマルチスレッドプログラミングを実行している場合に非常に便利です(データを共有するスレッドがキャッシュも共有していると、より良い結果が得られます)。


4
どのファイルにキャッシュラインサイズが含まれていますか?coherency_line_sizeを想定していますか?またはphysical_line_partition?
paxos1977 2009

27
coherency_line_size
スピンファイア

6
確かに:これはバイトです、そうですか?
Jakub M.

6
はい、coherency_line_sizeはバイト単位です。
John Zwinck、2011

4
@android:私は、core-i5プロセッサーを搭載したfedora-18 x64マシンを使用しています。私のシステムにcat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size戻ります64。index1、2、3フォルダーについても同様です。
アビッドラーマンK

141

Linuxでは、sysconf(3)を参照してください。

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

getconfを使用してコマンドラインから取得することもできます。

$ getconf LEVEL1_DCACHE_LINESIZE
64

4
簡単な答えが一番です!
FrankH。

3
@warunapwwバイト単位です。
Maarten Bamelis 2015年

最後に!より多くの人が時間の節約のためにこの答えを見てほしいと願っています。
elinx

118

私はいくつかのキャッシュラインに関するものに取り組んでおり、クロスプラットフォーム関数を書く必要がありました。https://github.com/NickStrupat/CacheLineSizeでgithubリポジトリにコミットしました。または、以下のソースを使用することもできます。好きなことを自由にしてください。

#ifndef GET_CACHE_LINE_SIZE_H_INCLUDED
#define GET_CACHE_LINE_SIZE_H_INCLUDED

// Author: Nick Strupat
// Date: October 29, 2010
// Returns the cache line size (in bytes) of the processor, or 0 on failure

#include <stddef.h>
size_t cache_line_size();

#if defined(__APPLE__)

#include <sys/sysctl.h>
size_t cache_line_size() {
    size_t line_size = 0;
    size_t sizeof_line_size = sizeof(line_size);
    sysctlbyname("hw.cachelinesize", &line_size, &sizeof_line_size, 0, 0);
    return line_size;
}

#elif defined(_WIN32)

#include <stdlib.h>
#include <windows.h>
size_t cache_line_size() {
    size_t line_size = 0;
    DWORD buffer_size = 0;
    DWORD i = 0;
    SYSTEM_LOGICAL_PROCESSOR_INFORMATION * buffer = 0;

    GetLogicalProcessorInformation(0, &buffer_size);
    buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)malloc(buffer_size);
    GetLogicalProcessorInformation(&buffer[0], &buffer_size);

    for (i = 0; i != buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
        if (buffer[i].Relationship == RelationCache && buffer[i].Cache.Level == 1) {
            line_size = buffer[i].Cache.LineSize;
            break;
        }
    }

    free(buffer);
    return line_size;
}

#elif defined(linux)

#include <stdio.h>
size_t cache_line_size() {
    FILE * p = 0;
    p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
    unsigned int i = 0;
    if (p) {
        fscanf(p, "%d", &i);
        fclose(p);
    }
    return i;
}

#else
#error Unrecognized platform
#endif

#endif

15
Linuxの場合はsysconf(_SC_LEVEL1_DCACHE_LINESIZE)を使用することをお勧めします。
Matt

@マットなぜですか?ちょっと興味があるんだけど :-)。
user35915

31

x86では、機能2でCPUID命令を使用して、キャッシュとTLBのさまざまなプロパティを決定できます。関数2の出力の解析はやや複雑なので、インテルプロセッサーの識別とCPUID命令(PDF)のセクション3.1.3を参照します。

C / C ++コードからこのデータを取得するには、インラインアセンブリ、コンパイラ組み込み関数を使用するか、外部アセンブリ関数を呼び出してCPUID命令を実行する必要があります。


誰もがキャッシュを内蔵した他のプロセッサでこれを行う方法を知っていますか?
paxos1977 2009

3
@ceretullis:エラー... x86にはキャッシュが組み込まれています。具体的にどの「その他のプロセッサ」を探していますか?あなたが求めているのはプラットフォームに依存しています。
ビリーONeal

9

SDL2を使用している場合は、次の関数を使用できます。

int SDL_GetCPUCacheLineSize(void);

L1キャッシュラインサイズのサイズをバイト単位で返します。

私のx86_64マシンで、次のコードスニペットを実行します。

printf("CacheLineSize = %d",SDL_GetCPUCacheLineSize());

生産する CacheLineSize = 64

少し遅れましたが、将来の訪問者のために情報を追加しています。SDLのドキュメントには現在、返される数値はKB単位であると記載されていますが、実際にはバイト単位です。


ああ、これは本当に役に立ちます。私はSDL2でゲームを書くつもりなので、これは本当に役立つでしょう
ニコラスハンフリー

7

Windowsプラットフォームの場合:

http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspxから

GetLogicalProcessorInformation関数は、システムで使用されている論理プロセッサの特性を提供します。RelationCacheタイプのエントリを探す関数によって返されたSYSTEM_LOGICAL_PROCESSOR_INFORMATIONをたどることができます。そのような各エントリには、エントリが適用されるプロセッサを示すProcessorMaskが含まれており、CACHE_DESCRIPTORでは、記述されているキャッシュのタイプとそのキャッシュのキャッシュラインの大きさを示します。


4

ARMv6 C0以降には、またはキャッシュタイプレジスタがあります。ただし、特権モードでのみ使用できます。

たとえば、Cortex™-A8テクニカルリファレンスマニュアルから

キャッシュタイプレジスタの目的は、命令およびデータキャッシュの最小ライン長をバイト単位で決定して、アドレスの範囲を無効にできるようにすることです。

キャッシュタイプレジスタは次のとおりです。

  • 読み取り専用レジスタ
  • 特権モードでのみアクセスできます。

キャッシュタイプレジスタの内容は、特定の実装によって異なります。図3-2は、キャッシュタイプレジスタのビット配置を示しています...


ARMプロセッサにキャッシュがあると想定しないでください(明らかに、キャッシュなしで構成できるものもあります)。それを決定する標準的な方法は、を使用することですC0ARM ARMから、ページB6-6:

ARMv6以降、システム制御コプロセッサのキャッシュタイプレジスタは、L1キャッシュを定義するための必須のメソッドです。B6-14ページの「キャッシュタイプレジスタ」を参照してください。これは、アーキテクチャの以前のバリアントにも推奨される方法です。また、B6-12ページの「キャッシュの追加レベルに関する考慮事項」では、レベル2キャッシュサポートのアーキテクチャガイドラインについて説明しています。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.