我正在尝试使用 masm32 程序集从主内存中读取数据,为了做到这一点,我创建了一个数组(正如之前在回答我的另一个问题时所建议的那样),该数组将包含大大分离的内存位置(以避免从缓存)。我已经成功创建了数组并读取了它,但是,我遇到了问题。我已经完成并测试的这个数组正在使用我提供的数据(即数字)并且一切正常。但我需要记忆位置,但在任何地方都找不到地图或参考资料。我的意思是我需要类似的东西:

my_arr db 5, 2, 8, 9, 1, 7, 3, 0, 4, 6

但我不应该使用数字,而应该使用相应的内存位置保留字。但我找不到它们 =( 甚至不知道还要寻找什么。


编辑

让我检查一下我是否正确,然后你告诉我我可以(而不是使用数组,使用变量之间的所有空格来强制从主内存读取,对吧?

有帮助吗?

解决方案

这是的(连续的)字节的数组,因为你说:

my_arr db 5, 2, 8, 9, 1, 7, 3, 0, 4, 6

这是占据10 MB(其相对于大到CPU高速缓冲存储器)的变量:

wasted_space BYTE 10485760 DUP(?)

下面是与之间的大量浪费空间几个变量:

my_var_1 db 5
spacer_1 BYTE 10485760 DUP(?)
my_var_2 db 2
spacer_2 BYTE 10485760 DUP(?)
my_var_3 db 8
spacer_3 BYTE 10485760 DUP(?)
my_var_4 db 9
spacer_4 BYTE 10485760 DUP(?)
my_var_5 db 1
spacer_5 BYTE 10485760 DUP(?)
my_var_6 db 7
spacer_6 BYTE 10485760 DUP(?)
my_var_7 db 3
spacer_7 BYTE 10485760 DUP(?)
my_var_8 db 0
spacer_8 BYTE 10485760 DUP(?)
my_var_9 db 4
spacer_8 BYTE 10485760 DUP(?)
my_var_10 db 6

这(创建您的数据段的变量)是得到一些数据存储器地址(变量不包含地址...相反,变量是在地址)。一个办法

要得到的存储器地址的另一种方法是调用O / S的API,其从堆中分配内存并返回分配的存储器的地址,例如也许HeapAlloc或的VirtualAlloc的API。


我不知道为什么你在ASM这样做(除了学习汇编)。如果是了解缓存,我还以为你能做到一样好(更容易)用C。

不管怎样,我得到了好奇缓存:是多大的空间足以引起高速缓存未命中?不同的变量多少是必要的开始,以使未命中(假定高速缓存被分割,因此可以包含几个(但只有少数)宽间隔的存储器高速缓存)?

有(缓存)已,多年来,成为一个复杂的问题,显然。 http://lwn.net/Articles/252125/ 是维基百科链接的文章。本文包括一些图表,例如的图3.11:连续读为多种尺寸

其他提示

汇编中的间接内存访问

要将数组中的字节视为内存地址,您需要将它们加载到可以用作基地址的寄存器中,然后访问寄存器指向的内存:

MOV AX, [MY_ARR+3]  ; Element 3 in array, that is 9
MOV BX, [AX]        ; Read from that address

关于缓存

请注意,您的缓存可能比该数组覆盖的内存地址范围大得多,因此所有内容都适合缓存。

另外,请考虑您的缓存可能是关联的,这意味着如果相距很远的地址不恰好位于相同(完整)缓存行上,则它们可以一起放入缓存中。

要实际耗尽缓存并保证您必须直接访问内存,您应该(在循环中)访问一组比缓存大的连续内存位置。IE。创建一个与缓存一样大的数组。还要考虑到可能有多层缓存(L1、L2,可能还有 L3 甚至更多),因此您需要多大取决于您想要溢出的缓存。


我用 C 编写了一个程序来对内存和缓存访问进行一次计时,并通过一些统计计算和对时间测量开销的补偿(在如此短的时间内是不可忽略的),得到了非常准确的结果(这可能是通过运行更长时间的测试并等待标准差下降来达到所需的准确度)。

然而,我的程序并不是最有效的方法,并且也没有太多关于缓存的关联性的暗示(我必须根据着色方案的知识单独测量它)。然而,两者都是以相对架构独立的方式相当有效地完成的,并在其中使用了一些深思熟虑的技巧。 Larry McVoy 和 Carl Staelin 的 SIGMETRICS 2005 作品.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top