How do I intentionally read from main memory vs cache?
Asked Answered
L

1

5

So I am being taught assembly and we have an assignment which is to find the time difference between reading from memory and reading from cache. We have to do this by creating 2 loops and timing them. (one reads from main memory and the other from cache). The thing is, I don't know and can't find anything that tells me how to read from either cache or main memory =/. Could you guys help me? I'm doing this in MASM32. I understand how to make loops and well most of the assembly language but I just can't make it read =/


Edit:

I have a question, I've done this ...

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

... would that be ok?


Edit 2:

well then, I don't intend to pry and I appreciate your help, I just have another question, since these are two loops I have to do. I need to compare them somehow, I've been looking for a timer instruction but I haven't found any I've found only: timeGetTime, GetTickCount and Performance Counter but as far as I understand these instructions return the system time not the time it takes for the loop to finish. Is there a way to actually do what I want? or I need to think of another way?

Also, to read from different registers in the second loop (the one not reading from cache) is it ok if I give various "mov" instructions? or am I totally off base here?

Sorry for all this questions but again thank you for your help.

Lipetsk answered 8/2, 2009 at 0:9 Comment(0)
M
7

To read from cache. have a loop which reads from the same (or very similar) memory address:

  • The first time you read from that address, the values from that memory address (and from other, nearby memory address) will be moved into cache
  • The next time you read from that same address, the values are already cached and so you're reading from cache.

To read uncached memory, have a loop which reads from many, very different (i.e. further apart than the cache size) memory addresses.


To answer your second question:

  • The things you're doing with ecx and jnz look OK (I don't know how accurate/sensitive your timer is, but you might want to loop more than 100 times)

  • The mov eax, eax is not "read memory" ... it's a no-op, which moves eax into eax. Instead, I think that the MASM syntax for reading from memory is something more like mov eax,[esi] ("read the from the memory location whose address is contained in esi")

  • Depending on what O/S you're using, you must read from a memory address which actually exists and is readable. On Windows, for example, an application wouldn't be allowed to do mov esi, 0 followed by mov eax, [esi] because an application isn't allowed to read the memory whose address/location is zero.


To answer your third question:

timeGetTime, GetTickCount and Performance Counter

Your mentioning timeGetTime, GetTickCount and Performance Counter implies that you're running under Windows.

Yes, these return the current time, to various resolutions/accuracies: for example, GetTickCount has a resolution of about 50 msec, so it fails to time events which last less than 50 msec, is inaccurate when timing events which last only 50-100 msec. That's why I said that 100 in your ecx probably isn't big enough.

The QueryPerformanceCounter function is probably the most accurate timer that you have.

To use any of these timers as an interval timer:

  • Get the time, before you start to loop
  • Get the time again, after you finish looping
  • Subtract these two times: the difference is the time interval

is it ok if I give various "mov" instructions?

Yes I think so. I think you can do it like this (beware I'm not sure/don't remember whether this is the right MASM syntax for reading from a name memory location) ...

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

... where memory1 through memory5 are addresses of widely-spaced global variables in your data segment.

Or, you could do ...

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]

... where esi is pointing to the bottom of a long chunk of memory, and edx is some increment that's equal to about a fifth of the length of the chunk.

Megalocardia answered 8/2, 2009 at 0:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.