Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 我如何有意识地从主内存和缓存中读取数据?_Performance_Caching_Assembly_Masm - Fatal编程技术网

Performance 我如何有意识地从主内存和缓存中读取数据?

Performance 我如何有意识地从主内存和缓存中读取数据?,performance,caching,assembly,masm,Performance,Caching,Assembly,Masm,所以我正在学习汇编,我们有一个任务,就是找出从内存读取和从缓存读取之间的时间差。我们必须通过创建两个循环并计时来实现这一点。(一个从主存读取,另一个从缓存读取)。问题是,我不知道也找不到任何东西告诉我如何从缓存或主内存读取=/。你们能帮帮我吗?我在MASM32里做这个。我知道如何进行循环,并且很好地理解了大多数汇编语言,但我就是不能让它阅读=/ 编辑: 我有个问题,我已经做了 mov ecx, 100 ;loop 100 times xor eax, eax ;set eax to 0 _la

所以我正在学习汇编,我们有一个任务,就是找出从内存读取和从缓存读取之间的时间差。我们必须通过创建两个循环并计时来实现这一点。(一个从主存读取,另一个从缓存读取)。问题是,我不知道也找不到任何东西告诉我如何从缓存或主内存读取=/。你们能帮帮我吗?我在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:

那么,我不想打听,我感谢你的帮助,我还有一个问题,因为这是我必须做的两个循环。我需要对它们进行比较,我一直在寻找一条计时器指令,但我没有找到任何我只找到的:timeGetTimeGetTickCount性能计数器,但据我所知,这些指令返回的是系统时间,而不是循环完成所需的时间。有没有办法真正做到我想要的?或者我需要想另一种方法

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


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

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

  • 第一次从该地址读取时,该内存地址(以及附近的其他内存地址)中的值将移动到缓存中
  • 下一次从该相同的地址读取时,值已被缓存,因此您正在从缓存中读取
要读取未缓存的内存,请使用一个循环,从许多非常不同(即,距离缓存大小更远)的内存地址读取


回答你的第二个问题:

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

  • mov eax,eax
    不是“读取内存”。。。这是一个no-op,它将eax移动到eax。相反,我认为用于从内存读取的MASM语法更像是
    mov eax[esi]
    (“从
    esi
    中包含地址的内存位置读取数据”)

  • 根据所使用的O/S,必须从实际存在且可读的内存地址读取。例如,在Windows上,不允许应用程序执行
    movesi,0
    ,然后执行
    moveax,[esi]
    ,因为不允许应用程序读取地址/位置为零的内存


回答你的第三个问题:

timeGetTime、GetTickCount和性能计数器

您提到的timeGetTime、GetTickCount和性能计数器意味着您正在Windows下运行

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

QueryPerformanceCounter
函数可能是您拥有的最精确的计时器

要将这些计时器中的任何一个用作间隔计时器,请执行以下操作:

  • 在开始循环之前,获取时间
  • 完成循环后,再次获取时间
  • 减去这两次:差就是时间间隔
如果我给出各种“mov”指令可以吗

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

。。。其中,
memory1
memory5
是数据段中大间距全局变量的地址

或者,你可以

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是一个增量,大约等于该内存块长度的五分之一

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]