3

假设我的数组是 32KB,L1 是 64KB。Windows 是否在程序运行时使用其中的一些?也许我无法使用 L1,因为 Windows 正在使其他程序工作?我应该设置程序的优先级以使用所有缓存吗?

for(int i=0;i<8192;i++)
{
  array_3[i]+=clock()*(rand()%256);//clock() and rand in cache too?
  //how many times do I need to use a variable to make it stay in cache?
  //or cache is only for reading? look below plz
  temp_a+=array_x[i]*my_function();
}

该程序使用 C/C++ 编写。

L2也一样。

功能是否也保存在缓存中?缓存是只读的?(如果我更改我的阵列,那么它会丢失缓存绑定?)

编译器是否创建 asm 代码以使用缓存更多产量?

谢谢

4

6 回答 6

14

我怎么知道我的数组在缓存中?

一般来说,你不能。一般来说,缓存是由硬件直接管理的,而不是由 Windows 管理的。您也无法控制数据是否驻留在缓存中(尽管可以指定不应缓存内存区域)。

Windows 在程序运行时会使用其中的一些吗?也许我无法使用 L1,因为 Windows 正在使其他程序工作?我应该设置程序的优先级以使用所有缓存吗?

L1 和 L2 缓存由给定内核上运行的所有进程共享。当您的进程运行时,它将使用所有缓存(如果需要)。当有上下文切换时,部分或全部缓存将被逐出,这取决于第二个进程需要什么。因此,下次有上下文切换回您的进程时,可能需要重新填充缓存。

但同样,这一切都是由硬件自动完成的。

函数也保存在缓存中?

在大多数现代处理器上,都有一个单独的指令缓存。参见这个图表,它显示了英特尔 Nehalem 架构的安排;注意共享的 L2 和 L3 高速缓存,但是用于指令和数据的单独的 L1 高速缓存。

缓存是只读的?(如果我更改我的数组,那么它会丢失缓存绑定?)

不可以。缓存可以处理修改过的数据,尽管这要复杂得多(因为在多核系统中同步多个缓存的问题。)

编译器是否创建 asm 代码以使用缓存更多产量?

由于缓存活动通常全部由硬件自动处理,因此不需要特殊指令。

于 2012-07-15T14:40:55.220 回答
1
  • 缓存不是由操作系统直接控制的,它是在硬件中完成的

  • 在上下文切换的情况下,另一个应用程序可能会修改缓存,但您不应该关心这一点。当您的程序表现出对缓存不​​友好的情况时,处理这种情况更为重要。

  • 函数保存在缓存中(I-Cahce,指令缓存)

  • 缓存不是只读的,当您编写某些内容时,它会进入[内存和]缓存。

于 2012-07-15T14:43:57.463 回答
1

据我所知,您无法控制缓存中的内容。您可以将变量声明为register var_type a,然后在单个周期(或少量周期)中访问它。此外,访问一块内存所需的周期数量还取决于虚拟内存转换和 TLB。应该注意的是 register 关键字只是一个建议,编译器可以完全自由地忽略它,正如评论所建议的那样。

于 2012-07-15T14:43:58.587 回答
1

缓存主要由硬件控制。但是,我知道 Windows 调度程序倾向于将线程的执行安排到与以前相同的核心,特别是因为缓存。它知道有必要将它们重新加载到另一个核心上。Windows 至少从 Windows 2000 开始就使用这种行为。

于 2012-07-15T14:45:48.133 回答
1

正如其他人所说,您通常无法控制缓存中的内容。如果您正在编写高性能代码并且需要依赖缓存来获得性能,那么编写代码以使用大约一半的 L1 缓存空间的情况并不少见。这样做的方法涉及大量超出 StackOverflow 问题范围的讨论。从本质上讲,您希望在处理其他数据之前对某些数据做尽可能多的工作。

至于实际可行的方法,使用大约一半的缓存会留下足够的空间让其他事情发生,您的大部分数据将保留在缓存中。如果没有操作系统和计算平台其他方面的合作,你就不能依赖它,所以它可能是加速研究计算的有用技术,但它不能用于必须保证实时性能的地方,比如操作危险的机器.

除了您使用多少数据之外,还有其他注意事项。即使有大量未使用的缓存,使用映射到相同缓存行的数据也可以从缓存中逐出数据。矩阵转置因此而臭名昭著,因为行长度是 2 的适中幂的倍数的矩阵将具有其中元素映射到一小组缓存行的列。所以学习有效地使用缓存是一项重要的工作。

于 2012-07-15T15:19:15.090 回答
1

即使您可能不知道哪些数据在缓存中,哪些不在缓存中,您仍然可能知道您正在使用多少缓存。现代处理器有很多性能计数器,其中一些与缓存有关。英特尔的处理器可能会告诉您有多少 L1 和 L2 未命中。检查此以获取有关如何执行此操作的更多详细信息:How to read performance counters on i5, i7 CPUs

于 2012-07-15T15:49:14.427 回答