Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “a”的价格是多少;“大的”;对象被带进缓存?_C++_Performance_Caching_Cpu_Cpu Architecture - Fatal编程技术网

C++ “a”的价格是多少;“大的”;对象被带进缓存?

C++ “a”的价格是多少;“大的”;对象被带进缓存?,c++,performance,caching,cpu,cpu-architecture,C++,Performance,Caching,Cpu,Cpu Architecture,如果我有一个包含多个大向量的对象,如果我访问其中一个向量数据成员,是否意味着其他向量(我没有访问)也会被带到缓存中(可能是根据代码的空间局部性规则) 如果我有: class A{ float p; int x[10000]; int y[10000]; }; 我只访问了一段特定代码中的p,访问a::p会不会比 class B{ float p; int x[10000]; double y; }; 因为B更小,因为只有一个大数组 我的直觉是,只

如果我有一个包含多个大向量的对象,如果我访问其中一个向量数据成员,是否意味着其他向量(我没有访问)也会被带到缓存中(可能是根据代码的空间局部性规则)

如果我有:

class A{
    float p;
    int x[10000];
    int y[10000];
};
我只访问了一段特定代码中的
p
,访问
a::p
会不会比

class B{
    float p;
    int x[10000];
    double y;
};
因为
B
更小,因为只有一个大数组


我的直觉是,只加载频繁访问的缓存线,而不是整个对象。

与您从中读取的地址相对应的缓存线被加载,而与对象无关

这取决于你的平台。对于64字节(8或16个整数)的缓存线,根据对齐方式,读取
x[0…15]
中的任何一个都只会导致在缓存中加载这些元素

读取元素
x[16]
将把它和后续元素加载到不同的缓存线中


根据缓存的总大小,读取(例如
x[9000]
)可能会导致缓存冲突,并且先前填充的行将被清除,以便为新元素腾出空间。

与读取的地址相对应的缓存行将被加载,而与对象无关

这取决于你的平台。对于64字节(8或16个整数)的缓存线,根据对齐方式,读取
x[0…15]
中的任何一个都只会导致在缓存中加载这些元素

读取元素
x[16]
将把它和后续元素加载到不同的缓存线中


根据缓存的总大小,读取(例如
x[9000]
)可能会导致缓存冲突,并且先前填充的行将被清除,以便为新元素腾出空间。

机器对类的布局一无所知,因此类大小无关。它只知道您实际访问的内存,即您的访问模式。一旦代码被编译,类的布局信息甚至可能不存在于内存中,因此机器无法计算出来。

机器对类的布局一无所知,因此类的大小无关紧要。它只知道您实际访问的内存,即您的访问模式。一旦代码被编译,类的布局信息甚至可能不存在于内存中,因此机器无法计算出来。

正如在其他答案中提到的,内存子系统不知道对象的内存布局。它只看到对相应地址的内存访问。因此,无论对象有多大,都会将相同数量的数据加载到缓存中

至于加载多少数据的问题,这取决于体系结构。在简单系统上,仅加载相应的缓存线。另一方面,现代x86CPU也有预取机制。此机制尝试确定下一步最可能需要的内存地址,并提前获取这些缓存线。这就是为什么顺序存取比随机存取快得多(数量级)的原因,因为在这里,预取程序总是选择正确的数据

编辑:
但同样:这与类的大小无关,只取决于访问模式(当然可能取决于类的内存布局)。

正如其他答案中提到的,内存子系统不知道对象的内存布局。它只看到对相应地址的内存访问。因此,无论对象有多大,都会将相同数量的数据加载到缓存中

至于加载多少数据的问题,这取决于体系结构。在简单系统上,仅加载相应的缓存线。另一方面,现代x86CPU也有预取机制。此机制尝试确定下一步最可能需要的内存地址,并提前获取这些缓存线。这就是为什么顺序存取比随机存取快得多(数量级)的原因,因为在这里,预取程序总是选择正确的数据

编辑:
但同样:这与类的大小无关,只取决于访问模式(当然可能取决于类的内存布局)。

缓存行为取决于机器。如果加载一块内存,周围的内存可能也会被缓存,但缓存的内存大小与结构的外观无关,因为您的计算机不知道结构是什么,也不关心您是否认为其成员属于同一个结构。缓存线的大小是一定的,可能是128字节。如果必须访问该行中的任何字节,则会引入整行(甚至是不相关对象中的字节)。在最简单的缓存方案中,在引用它们之前不会引入额外的字节。这对答案没有影响,但就内存布局而言,这是两件完全不同的事情。向量在堆上单独的内存区域管理它们的内存,而c数组的变量实际上是在对象内存区域内分配的。缓存行为依赖于机器。如果加载一块内存,周围的内存可能也会被缓存,但缓存的内存大小与结构的外观无关,因为您的计算机不知道结构是什么,也不关心您是否认为其成员属于同一个结构。缓存线的大小是一定的,可能是128字节。如果必须访问该行中的任何字节,则会引入整行(甚至是不相关对象中的字节)。简单地说