すべてのプラットフォームを歓迎します。回答のプラットフォームを指定してください。
SDL_GetCPUCacheLineSize
関数のソースコードを調べ(negamartinの回答から情報を展開)cpuid macro
、それぞれにアセンブリソースコードがあるかどうかを確認できます。プロセッサモデルの。あなたは見てみることができimgur.com/a/KP57m6s、または直接ソースを自分で覗い。
すべてのプラットフォームを歓迎します。回答のプラットフォームを指定してください。
SDL_GetCPUCacheLineSize
関数のソースコードを調べ(negamartinの回答から情報を展開)cpuid macro
、それぞれにアセンブリソースコードがあるかどうかを確認できます。プロセッサモデルの。あなたは見てみることができimgur.com/a/KP57m6s、または直接ソースを自分で覗い。
回答:
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がこのキャッシュを共有しているものなど、知りたいと思うキャッシュに関する詳細情報が得られます。これは、共有データを使用してマルチスレッドプログラミングを実行している場合に非常に便利です(データを共有するスレッドがキャッシュも共有していると、より良い結果が得られます)。
cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
戻ります64
。index1、2、3フォルダーについても同様です。
Linuxでは、sysconf(3)を参照してください。
sysconf (_SC_LEVEL1_DCACHE_LINESIZE)
getconfを使用してコマンドラインから取得することもできます。
$ getconf LEVEL1_DCACHE_LINESIZE
64
私はいくつかのキャッシュラインに関するものに取り組んでおり、クロスプラットフォーム関数を書く必要がありました。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
x86では、機能2でCPUID命令を使用して、キャッシュとTLBのさまざまなプロパティを決定できます。関数2の出力の解析はやや複雑なので、インテルプロセッサーの識別とCPUID命令(PDF)のセクション3.1.3を参照します。
C / C ++コードからこのデータを取得するには、インラインアセンブリ、コンパイラ組み込み関数を使用するか、外部アセンブリ関数を呼び出してCPUID命令を実行する必要があります。
SDL2を使用している場合は、次の関数を使用できます。
int SDL_GetCPUCacheLineSize(void);
L1キャッシュラインサイズのサイズをバイト単位で返します。
私のx86_64マシンで、次のコードスニペットを実行します。
printf("CacheLineSize = %d",SDL_GetCPUCacheLineSize());
生産する CacheLineSize = 64
少し遅れましたが、将来の訪問者のために情報を追加しています。SDLのドキュメントには現在、返される数値はKB単位であると記載されていますが、実際にはバイト単位です。
Windowsプラットフォームの場合:
http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspxから
GetLogicalProcessorInformation関数は、システムで使用されている論理プロセッサの特性を提供します。RelationCacheタイプのエントリを探す関数によって返されたSYSTEM_LOGICAL_PROCESSOR_INFORMATIONをたどることができます。そのような各エントリには、エントリが適用されるプロセッサを示すProcessorMaskが含まれており、CACHE_DESCRIPTORでは、記述されているキャッシュのタイプとそのキャッシュのキャッシュラインの大きさを示します。
ARMv6 C0
以降には、またはキャッシュタイプレジスタがあります。ただし、特権モードでのみ使用できます。
たとえば、Cortex™-A8テクニカルリファレンスマニュアルから:
キャッシュタイプレジスタの目的は、命令およびデータキャッシュの最小ライン長をバイト単位で決定して、アドレスの範囲を無効にできるようにすることです。
キャッシュタイプレジスタは次のとおりです。
- 読み取り専用レジスタ
- 特権モードでのみアクセスできます。
キャッシュタイプレジスタの内容は、特定の実装によって異なります。図3-2は、キャッシュタイプレジスタのビット配置を示しています...
ARMプロセッサにキャッシュがあると想定しないでください(明らかに、キャッシュなしで構成できるものもあります)。それを決定する標準的な方法は、を使用することですC0
。ARM ARMから、ページB6-6:
ARMv6以降、システム制御コプロセッサのキャッシュタイプレジスタは、L1キャッシュを定義するための必須のメソッドです。B6-14ページの「キャッシュタイプレジスタ」を参照してください。これは、アーキテクチャの以前のバリアントにも推奨される方法です。また、B6-12ページの「キャッシュの追加レベルに関する考慮事項」では、レベル2キャッシュサポートのアーキテクチャガイドラインについて説明しています。
いくつかのタイミングを測定することにより、プログラムでそれを試すこともできます。明らかに、それは常にcpuidなどほど正確ではありませんが、より移植性があります。ATLASはその構成段階でそれを実行します。