5

所以我正在学习汇编,我们有一个任务是找到从内存读取和从缓存读取之间的时间差。我们必须通过创建 2 个循环并对它们进行计时来做到这一点。(一个从主存读取,另一个从缓存中读取)。问题是,我不知道也找不到任何告诉我如何从缓存或主内存中读取的东西=/。你们能帮帮我吗?我在 MASM32 中这样做。我了解如何制作循环以及大多数汇编语言,但我就是无法阅读 =/


编辑:

我有一个问题,我已经这样做了......

mov ecx, 100 ;loop 100 times
xor eax, eax ;set eax to 0
_label:
mov eax, eax ;according to me this is read memory is that good?
dec ecx ;dec loop
jnz _label ;if still not equal to 0 goes again to _label

……这样可以吗?


编辑2:

那么,我不打算撬,感谢您的帮助,我还有另一个问题,因为这是我必须做的两个循环。我需要以某种方式比较它们,我一直在寻找计时器指令,但我没有找到任何我只找到的:timeGetTimeGetTickCountPerformance Counter但据我了解,这些指令返回系统时间而不是时间循环完成。有没有办法真正做我想做的事?还是我需要考虑另一种方式?

此外,如果我给出各种“mov”指令,可以在第二个循环中读取不同的寄存器(不从缓存中读取的寄存器)吗?还是我完全不在这儿?

很抱歉所有这些问题,但再次感谢您的帮助。

4

1 回答 1

7

从缓存中读取。有一个从相同(或非常相似)的内存地址读取的循环:

  • 第一次从该地址读取时,该内存地址(以及其他附近的内存地址)中的值将被移动到缓存中
  • 下次您从同一个地址读取时,这些值已经被缓存,因此您正在从缓存中读取。

要读取未缓存的内存,请使用一个从许多非常不同(即比缓存大小相距更远)的内存地址读取的循环。


回答你的第二个问题:

  • 你用 ecx 和 jnz 做的事情看起来不错(我不知道你的计时器有多准确/敏感,但你可能想要循环超过 100 次)

  • mov eax, eax不是“读取内存”......它是一个无操作,它将 eax 移动到 eax。相反,我认为从内存中读取的 MASM 语法更像是mov eax,[esi](“从地址包含在esi”中的内存位置读取)

  • 根据您使用的操作系统,您必须从实际存在且可读的内存地址中读取。例如,在 Windows 上,不允许应用程序执行mov esi, 0后面的操作,mov eax, [esi]因为不允许应用程序读取地址/位置为零的内存。


回答你的第三个问题:

timeGetTime、GetTickCount 和性能计数器

您提到 timeGetTime、GetTickCount 和 Performance Counter 意味着您在 Windows 下运行。

是的,这些将当前时间返回到各种分辨率/精度:例如,GetTickCount 的分辨率约为 50 毫秒,因此它无法对持续时间少于 50 毫秒的事件进行计时,当对仅持续 50-100 的事件进行计时时不准确毫秒。这就是为什么我说100你的ecx可能还不够大。

QueryPerformanceCounter功能可能是您拥有的最准确的计时器。

要将这些计时器中的任何一个用作间隔计时器:

  • 在开始循环之前花点时间
  • 完成循环后再次获取时间
  • 减去这两次:差就是时间间隔

如果我给出各种“mov”指令可以吗?

是的,我想是这样。我认为您可以这样做(请注意,我不确定/不记得这是否是从名称存储位置读取的正确 MASM 语法)...

mov eax,[memory1]
mov eax,[memory2]
mov eax,[memory3]
mov eax,[memory4]
mov eax,[memory5]

... 其中memory1throughmemory5是数据段中间隔较宽的全局变量的地址。

或者,你可以做...

mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]

...其中 esi 指向一个长内存块的底部,而 edx 是一些增量,等于该块长度的大约五分之一。

于 2009-02-08T00:13:55.883 回答