x86 Assembly Force缓存存储

mrk*_*aly 6 c x86 assembly caching

我有一个任务,我需要测量访问L1,L2和L3缓存中的数据的延迟,以及主内存.这将在C中完成.

我花了几个小时研究测量缓存延迟的方法,并且调整得很少.我已经下载了一些基准测试工具,这些工具给了我缓存访问时间,但在我自己的代码中实现它时,我还没有得到任何结论.我知道缓存中发生的事情在C中不符合我的要求.

我的下一个想法是,如果我可以强制使用来自x86程序集的东西填充缓存(首先想到)然后只对我刚刚加载的数据做一个clock(),access(),clock(),据说时间就是准确的(是)访问时间,因为我知道它应该在缓存中找到,因为我只是用我的内联asm或类似的方法把它放在那里...

如果有人能够在这里为我的任务提供见解,那将是非常棒的.是否告诉我,我因为想要使用asm在缓存中加载某些东西而疯狂,或者向我介绍可能对我有帮助的其他东西.

非常感谢!

old*_*mer 8

根本没有理由使用汇编进行此分配.您的解决方案不需要程序集C也可以正常工作.我假设您在操作系统之上运行,因此这将妨碍您的测量,既可以执行您认为自己知道的位置,也可以测量您认为自己正在测量的内容.

关于进行这些测量的缓存基础知识......假设有四层内存.L1,最快,但也最贵,最小.L2然后.较慢,不那么昂贵,可能比L1大.L3更便宜,更慢,更大,然后主内存最慢,最便宜,最大.

让我们说我们有四块内存,我们将使用A,B,C和D.L1一次只能容纳一个块.L2一次两个,L3中的三个和主存全部四个.

如果我们进行读取,它首先通过L1,如果有未命中则L2,如果未命中则L3,如果未命中,则它将始终在主存储器中.理解虽然这些数据在返回途中被缓存,因此L3,L2和L1都将包含刚刚读取的数据,必要时进行驱逐(并非总是如此,但假设这个简单的缓存模型可以理解如何完成任务).因此,如果我们读取块A,那么L1,L2和L3都将包含块A.现在在这个假设模型中,如果我们读取块B,那么L1将包含B,驱逐A.L2将包含A和b,l3将包含A和B.读C和L1将包含C,驱逐B,假设L2选择驱逐A,并包含B和C,L3包含A,B和C.读D和L1将包含C让我们说L2驱逐B并包含C和D,并说L3驱逐A并包含B,C和D.

假设我们并不完全知道每个缓存如何选择要驱逐的内容和要保留的内容.但是假设我们知道或者可以从主板规格或其他来源中找出每个缓存有多大.如果上述例子按此顺序发生且L1具有D,则L2具有C和D,L3具有B,C和D,并且main具有全部四个a,b,c,d.然后,如果在那个状态下我们读取所有块A和时间它我们理论上从主存储器中读取它,它不仅仅是读取该存储器的时间,而且如果任何被驱逐的存储器已经改变它必须写在上游可能的命中一路.但理想情况下,如果你大部分只是读取,那么你将主要读取时间.

让我们说我们发现自己处于大块D在l1,c和d中的l2,b,c,d在l3中的情况,我们读取了所有的块B并计时.这不是衡量访问L3的时间吗?使用相同的起始条件然后读取C将给我们l2时间.有了相同的起始条件,那么读取D将是l1时间对吗?

诀窍是让自己进入这些条件.缓存的大小可能不会使l2的大小是l1的两倍,依此类推,因此要完全控制L1中的内容,您需要读取足够的数据来填充L1.此外,如果您要读取L3大小的数据量,那么理论上L3具有所有数据,L2具有该数据的最后L2量,而L1具有该数据的最后L1量.

使用数据缓存比指令缓存更容易,但您可以这样做,在主内存中至少需要L3大小的指令,大量的nops.执行线性指令块与读取线性内存块没有什么不同.就读周期而言.就启用和使用I缓存而言,指令更容易.根据您的操作系统以及如何管理内存,启用数据缓存可能也可能不简单.