C++ 确定CPU缓存中的值和/或值地址

C++ 确定CPU缓存中的值和/或值地址,c++,c,windows,memory-management,cpu-cache,C++,C,Windows,Memory Management,Cpu Cache,对于当前进程或所有进程,是否有方法确定CPU缓存L1、L2等中当前驻留的值、内存地址和/或其他信息 我已经读了很多关于如何优化程序以更有效地利用CPU缓存的文章。然而,我正在寻找一种方法来真正确定某些方法是否有效 一句话:是否有可能100%确定哪些内容会和哪些内容不会进入CPU缓存 搜索此主题将返回有关如何确定缓存大小的多个结果,但不会返回内容 编辑:为了澄清下面的一些评论:由于软件无疑会改变缓存,CPU制造商是否内置了提供此功能的工具/硬件诊断系统?如果不使用专用硬件,您无法直接检查CPU缓存

对于当前进程或所有进程,是否有方法确定CPU缓存L1、L2等中当前驻留的值、内存地址和/或其他信息

我已经读了很多关于如何优化程序以更有效地利用CPU缓存的文章。然而,我正在寻找一种方法来真正确定某些方法是否有效

一句话:是否有可能100%确定哪些内容会和哪些内容不会进入CPU缓存

搜索此主题将返回有关如何确定缓存大小的多个结果,但不会返回内容


编辑:为了澄清下面的一些评论:由于软件无疑会改变缓存,CPU制造商是否内置了提供此功能的工具/硬件诊断系统?

如果不使用专用硬件,您无法直接检查CPU缓存中的内容。运行任何软件检查CPU缓存的行为都会改变缓存的状态


我发现的最好的方法就是简单地确定应用程序中的真正热点,并在硬件上对替代算法进行基准测试。如果您无法控制生产环境,代码将在生产中运行,或者在一系列可能的硬件上运行。

无需使用专用硬件,您不能直接检查CPU缓存中的内容。运行任何软件检查CPU缓存的行为都会改变缓存的状态


我发现的最好的方法是简单地确定应用程序中的真正热点,并在硬件上对替代算法进行基准测试。如果您无法控制生产环境,代码将在生产中运行,或者在一系列可能的硬件上运行。

除了Eric J.的答案,我要补充一点,虽然我确信大型芯片制造商确实有这样的工具,但像你我这样的普通人不太可能使用这样的调试工具,但即使是这样,也不会有多大帮助

为什么??您不太可能遇到已跟踪到缓存的性能问题,而这些问题无法使用维护高缓存命中率的众所周知和常识性技术来解决

您是否真的优化了代码中的所有其他热点,CPU的缓存行为差是问题所在?我对此深表怀疑


此外,值得思考的是:您真的希望只针对一个或两个特定CPU优化程序的行为吗?毕竟,缓存算法一直在变化,缓存的参数也在变化,有时会发生戏剧性的变化。

除了Eric J.的回答,我还要补充一点,虽然我确信大型芯片制造商确实有这样的工具,但像你我这样的普通人不太可能使用这样的调试工具,但即使是这样,这真的没有多大帮助

为什么??您不太可能遇到已跟踪到缓存的性能问题,而这些问题无法使用维护高缓存命中率的众所周知和常识性技术来解决

您是否真的优化了代码中的所有其他热点,CPU的缓存行为差是问题所在?我对此深表怀疑


此外,值得思考的是:您真的希望只针对一个或两个特定CPU优化程序的行为吗?毕竟,缓存算法一直在变化,缓存的参数也在变化,有时变化很大。

如果你有一个运行Windows的相对现代的处理器,那么看看
如果你有一个运行Windows的相对现代的处理器,那么看看
看看这是否能提供一些您想要的东西。

为一个特定的CPU缓存大小进行优化通常是徒劳的,因为当您在不同的CPU上执行时,如果您对CPU缓存大小的假设是错误的,那么这种优化就会失败

但是有一条出路。您应该针对某些访问模式进行优化,以允许CPU轻松预测下一步应该读取哪些内存位置最明显的是线性递增读取。为了能够充分利用CPU,您应该了解算法,其中大多数算法都遵循分而治之的策略,即在一定程度上将问题划分为子部分,直到所有内存访问完全适合CPU缓存

值得一提的是,代码和数据缓存是分开的。Herb Sutter有一个很好的在线论坛,他在那里深入讨论了CPU的内部结构

可以收集处理内存的CPU计数器和L2计数器。选择instrumentation profiling时,这些选项可用

英特尔还更详细地讨论了这些CPU计数器,以及Windows和Linux的任务管理器向您展示了什么,以及对于今天的内部工作异步的CPU来说这是多么错误 d在许多不同的层次上是平行的。不幸的是,英特尔没有直接显示这些内容的工具。我知道的唯一工具是VS分析器。也许VTune具有类似的功能

如果您在优化代码方面已经走了这么远,那么您也可以研究GPU编程。您至少需要一个博士学位才能了解SIMD指令、缓存位置。。。在你的原始设计上获得一个因子5。但是,通过将算法移植到GPU上,在一个像样的图形卡上,您只需花费更少的精力就可以获得100倍。NVidia GPU支持现在出售的所有卡,可以很好地用C语言编程。甚至还有托管代码.NET的包装器来利用GPU的全部功能


您可以通过使用保持平台无关性,但NVidia OpenCL支持非常糟糕。OpenCL驱动程序的速度至少是CUDA驱动程序的8倍

为一个特定的CPU缓存大小进行优化通常是徒劳的,因为当您在不同的CPU上执行时,如果您对CPU缓存大小的假设是错误的,则此优化将被打破

但是有一条出路。您应该针对某些访问模式进行优化,以允许CPU轻松预测下一步应该读取哪些内存位置最明显的是线性递增读取。为了能够充分利用CPU,您应该了解算法,其中大多数算法都遵循分而治之的策略,即在一定程度上将问题划分为子部分,直到所有内存访问完全适合CPU缓存

值得一提的是,代码和数据缓存是分开的。Herb Sutter有一个很好的在线论坛,他在那里深入讨论了CPU的内部结构

可以收集处理内存的CPU计数器和L2计数器。选择instrumentation profiling时,这些选项可用

英特尔还更详细地讨论了这些CPU计数器,以及Windows和Linux的任务管理器向您展示了什么,以及今天的CPU在许多不同级别的内部异步和并行工作是多么错误。不幸的是,英特尔没有直接显示这些内容的工具。我知道的唯一工具是VS分析器。也许VTune具有类似的功能

如果您在优化代码方面已经走了这么远,那么您也可以研究GPU编程。您至少需要一个博士学位才能了解SIMD指令、缓存位置。。。在你的原始设计上获得一个因子5。但是,通过将算法移植到GPU上,在一个像样的图形卡上,您只需花费更少的精力就可以获得100倍。NVidia GPU支持现在出售的所有卡,可以很好地用C语言编程。甚至还有托管代码.NET的包装器来利用GPU的全部功能


您可以通过使用保持平台无关性,但NVidia OpenCL支持非常糟糕。OpenCL驱动程序的速度至少是CUDA驱动程序的8倍

除非您正在读取配置为不可缓存的内存(通常是图形卡的帧缓冲内存),否则在使用缓存时,您所做的几乎所有事情都将在缓存中。另一种不命中缓存的方法是使用非时态的特定加载和存储指令。在到达CPU内部的目标寄存器之前,所有其他内容都会读入一级缓存

几乎在所有情况下,CPU都有一个相当好的系统,知道在缓存中保留什么和丢弃什么,并且缓存几乎总是满的——不一定是有用的东西,例如,如果您正在处理一个巨大的数组,它将只包含很多旧的数组[这就是非时态内存操作的用武之地,因为它们允许您读取和/或写入不会存储在缓存中的数据,因为下次回到同一点时,它无论如何都不会在缓存中]

是的,处理器通常有特殊的寄存器[可以在内核驱动程序中访问]这可以检查缓存的内容。但是它们很难使用,同时又不会丢失缓存的内容。而且它们绝对没有用,因为在缓存类型检查中有多少数组A。它们是专门为Hmm设计的,看起来缓存线1234被破坏了,我最好读取缓存的数据,看看它是否真实当处理器不能正常工作时,它应该是什么值


正如DanS所说,您可以从合适的软件中读取性能计数器[也需要在内核中使用这些寄存器,因此您需要某种驱动程序软件].在Linux中,有性能计数器,AMD有一组类似的性能计数器,可以用来找出,例如,在这段时间内我们有多少次缓存未命中,或者在L中有多少次缓存命中,等等。

当您使用它时,您所做的几乎所有事情都将在缓存中,除非您 重新读取已配置为不可缓存的内存—通常是图形卡的帧缓冲内存。另一种不命中缓存的方法是使用非时态的特定加载和存储指令。在到达CPU内部的目标寄存器之前,所有其他内容都会读入一级缓存

几乎在所有情况下,CPU都有一个相当好的系统,知道在缓存中保留什么和丢弃什么,并且缓存几乎总是满的——不一定是有用的东西,例如,如果您正在处理一个巨大的数组,它将只包含很多旧的数组[这就是非时态内存操作的用武之地,因为它们允许您读取和/或写入不会存储在缓存中的数据,因为下次回到同一点时,它无论如何都不会在缓存中]

是的,处理器通常有特殊的寄存器[可以在内核驱动程序中访问]这可以检查缓存的内容。但是它们很难使用,同时又不会丢失缓存的内容。而且它们绝对没有用,因为在缓存类型检查中有多少数组A。它们是专门为Hmm设计的,看起来缓存线1234被破坏了,我最好读取缓存的数据,看看它是否真实当处理器不能正常工作时,它应该是什么值


正如DanS所说,您可以从合适的软件中读取性能计数器[也需要在内核中使用这些寄存器,因此您需要某种驱动程序软件]。在Linux中,有性能。AMD有一组类似的性能计数器,可以用来找出,例如,在这段时间内我们有多少次缓存未命中,或者在L中有多少次缓存命中,等等。

有趣的是,如果不改变其状态,就无法观察系统。@SethCarnegie显然是一个很好的观点。现在我很好奇我们是否有一个内置的硬件诊断工具/子系统允许这样做。@SethCarnegie:我假设芯片制造商有专门的硬件来检查缓存状态,以便测试和诊断新的芯片组。但是你不能在不改变它的情况下使用软件检查缓存。对否决票感到好奇。我相信这符合所有要求关于这个问题。有趣的是,如果不改变系统的状态,系统是无法被观察到的。@SethCarnegie显然是一个很好的观点。现在我很好奇是否有一个内置的硬件诊断工具/子系统允许这样做。@SethCarnegie:我假设芯片制造商有专门的硬件来检查缓存状态,以便测试和诊断新的缓存芯片组。但是你不能在不修改的情况下使用软件检查缓存。对下一票很好奇。我相信这满足了关于这一问题的所有要求。虽然不是我所寻找的100%,但它提供了比其他产品更多的价值。虽然不是我所寻找的100%,但它提供了比其他产品更多的价值。