访问单个结构成员是否会将整个结构拉入缓存? [英] Does accessing a single struct member pull the entire struct into the Cache?

查看:58
本文介绍了访问单个结构成员是否会将整个结构拉入缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读Ulrich Drepper的文章,"每个程序员应该了解的内存"和在 3.3.2缓存效果的测量(页面的一半)中,给我的印象是访问结构的任何成员都会导致整个结构被拉入CPU缓存.

I've been reading Ulrich Drepper's, "What every programmer should know about memory" and in section 3.3.2 Measurements of Cache Effects ( halfway down the page ) it gives me the impression that accessing any member of a struct causes the whole struct to get pulled into the CPU cache.

这是正确的吗?如果是这样,硬件如何知道这些结构的布局?还是编译器生成的代码以某种方式迫使整个结构被加载?

Is this correct? If so, how does the hardware know about the layout of these structs? Or does the code generated by the compiler somehow force the entire struct to be loaded?

还是主要由于结构分散在更多内存页面上而导致TLB丢失而导致使用较大结构的速度变慢?

Or are the slowdowns from using larger structs primarily due to TLB misses caused by the structs being spread out across more memory pages?

Drepper使用的示例结构为:

The example struct used by Drepper is:

  struct l {
    struct l *n;
    long int pad[NPAD];
  };

其中 sizeof(l) NPAD 确定等于0、7、15或31的结构导致相隔0、56、120和248个字节的结构,以及假设缓存行为64字节和4k页.

Where sizeof(l) is determined by NPAD equals 0, 7, 15 or 31 resulting in structs that are 0, 56, 120, and 248 bytes apart and assuming cache lines that are 64 bytes and 4k pages.

即使结构实际上正在访问指针,但随着结构的增长,仅循环访问链表会变得很慢.

Just iterating through the linked list gets significantly slower as the struct grows, even though nothing other than the pointer is actually being accessed.

推荐答案

硬件完全不了解该结构.但是的确,缓存中的硬件负载实际上是您实际访问的字节周围的一些字节.这是因为高速缓存行具有大小.它不适用于逐字节访问,但适用于一次16个字节大小.

The hardware does not know at all about the struct. But it is true that the hardware load in the cache some bytes around the bytes you are actually accessing. This is because the cache line has a size. It does not work on a byte by byte access but on e.g. 16 bytes size at a time.

在订购结构的成员时必须小心,以使经常使用的成员彼此靠近.例如,如果您具有以下结构:

You have to be careful when ordering the members of the struct so that often used members are close to each other. For instance if you have the following struct:

struct S {
  int foo;
  char name[64];
  int bar;
};

如果经常使用成员变量foo和bar,则硬件将在缓存中加载foo周围的字节,并且当您访问bar时,它将必须加载bar周围的字节.即使foo和bar周围的这些字节都从未使用过.现在,按如下所示重写您的结构:

If the member variables foo and bar are used very often, the hardware will load in cache the bytes around foo, and when you'll access bar, it will have to load the bytes around bar. Even if these bytes around foo and around bar are never used. Now rewrite your struct as follows:

struct S {
  int foo;
  int bar;
  char name[64];
};

当您使用foo时,硬件将在缓存中加载foo周围的字节.当您使用bar时,bar将已经在缓存中,因为bar包含在foo周围的字节中.CPU不必等待bar进入缓存.

When you'll use foo, the hardware will load in cache the bytes around foo. When you'll use bar, bar will already be in the cache because bar is contained in the bytes around foo. The CPU won't have to wait for bar to be in the cache.

答案是 :访问单个结构成员不会将整个结构拉入缓存中,而是会将结构的其他成员拉入缓存中.

Answer is: accessing a single struct member does not pull the entire struct in the cache, but pull some other member of the struct into the cache.

这篇关于访问单个结构成员是否会将整个结构拉入缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆