我们如何知道struct是在CPU缓存上还是丢失到内存缓存中?

时间:2018-09-05 14:49:55

标签: c# .net performance cpu-cache

我正在尝试编写C#游戏框架,因此此处的性能至关重要。

这是我找到的reference

问题是,我们如何知道结构是否仍在CPU缓存中?

如果不能,那么在什么情况下将结构推到内存缓存中。

例如,将结构推送到List <>,然后再访问它们,它是否仍在CPU缓存中?

2 个答案:

答案 0 :(得分:3)

问题的几乎所有答案都取决于它,但是您可以通过调试进程并监视“ Debug-> Windows-> Registers” 来查看CPU缓存中是否有东西内存地址被加载到每个寄存器中,并逐步执行代码,您可以看到什么东西进出。这是我所能做到的。

我建议您使用benchmarking进行微优化,只有在那之后才开始挖掘较低的细节。

答案 1 :(得分:2)

  

我们如何知道结构是否仍在CPU缓存中?

不,不需要知道。

  

如果不能,那么在什么情况下将结构推到内存缓存中。

它在处理时将完全存在,但将在处理后丢弃。

  

将结构推送到List <>,然后稍后访问它们,它是否仍在CPU缓存中?

Push a struct to List<>是一项内存操作,CPU会执行push操作,但可能根本不需要加载它,它只能更改pointer。但是如果稍后CPU需要这些数据,则将partiallysequentially完全加载到CPU缓存中。

要通过软件优化缓存性能,将其称为Cache-Conscious Data Structure,以制作Pointer Based Data Structures Cache Conscious,这将大大提高性能。大约15年前,我用C做了一个测试,它极大地提高了性能,提高了70%以上,但是现在我丢失了那些代码。

您必须先熟练使用性能工具:

  1. Visual studio performance tools为您提供识别任何级别的代码消耗性能的一般方法。
  2. 这篇帖子Value Types vs Reference Types提供了一个关于Benchmark Runner的很好的例子

不可能实现可以满足所有建议的框架,就像您引用的example一样。我认为您可以放置​​一个上下文,然后我们继续讨论。

与内存相比,CPU缓存要小得多,它的单元仅加载所需的数据,然后在处理后立即将其处理,然后将下一个数据加载到下一个内存地址(如果有),但是引用类型可以在其他地方存储NEXT数据,但是不是NEXT位置,这会降低其定位性能。这就是为什么出现3级缓存,第3个缓存将尝试定位第2个数据,然后第1个将从较快的缓存中使用它的原因。

List<T>是一种引用类型,它将在heap的不同内存块中托管一个实例,然后使性能稍差一些,但是值类型对象使用stack,这可以将数据保留在一起,然后CPU可以更快地加载它们,但是您还必须指定操作来改善您的情况,在任何实际项目中,它并不总是通用的。

实际上,为了提高性能,LINQ将许多类型的对象转换为值类型structure,而不是继续使用class本身。