高速缓存行检索和在大型数据结构上的性能

cache line retrieval and performance on large data structure

本文关键字:数据结构 结构上 性能 数据 大型 检索 高速缓存      更新时间:2023-10-16

假设我有一个非常大的数据结构,它比硬件的缓存线大得多(请参阅下面的示例)。让我们假设我想

  1. 读取和写入位于第一高速缓存行的CCD_ 1
  2. 那么我想读取和写入位于2个缓存行之后的CCD_ 2
  3. 现在我可能还想要读取和写入位于第二高速缓存行中的成员,即中间行memb_ten_中的成员。这种情况并不总是发生

所以我需要经常执行步骤1。以及步骤2。但并不总是步骤3。不幸的是,我无法更改结构的布局。

我的问题如下:在步骤1之后。以及步骤2.,第二个高速缓存行,即中间的高速缓存行是否从存储器检索到L1中?

据我所知,在L1中检索到的缓存行只是通过读取/写入位于其中的结构成员而"触及"的缓存行。这基本上意味着在L1中只有结构实例的一部分可用。

如果我的理解是正确的,是否有强制所有3条缓存线的请求?当我需要的时候,我想通过在第二个缓存行上写来避免缓存丢失

如果没有这样的机制,你认为我可以从使用共享相同缓存的后台线程并频繁读取这些实例以保持缓存行"热"中受益吗?为了避免错误的共享效果或过多的数据总线流量,该线程永远不会写入。

 struct VeryBigStruct 
 { 
   // first cahce line..
   int memb_one_;
   ...
   // second cahce line..
   int memb_ten_;
   ...
   // third cache line
   int memb_forty_;
   ...
 }

我在Linux上使用g++ 4.7 and 4.9

否,触摸第一个和第三个缓存线后,第二个缓存线不保证在一级缓存中。但是,如果访问频率足够高,它可能就在那里。

如果后台线程与主线程在同一物理核心中运行,那么它可能只会帮助将数据放入一级缓存。您可以为线程设置CPU相关性以实现此效果。

在gcc中,有一个内置函数用于预取要缓存的存储器地址,它被称为:

__builtin_prefetch(&your_struct_ptr->memb_ten_, 1, 3);

或者你可以这样做:

#include <xmmintrin.h>
...
_mm_prefetch(&your_struct_ptr->memb_ten_, _MM_HINT_ET0);

请参见此处:https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html在这里:https://software.intel.com/en-us/node/524263

[我认为您使用的是x86或x86-64体系结构。]