Как мне намеренно считывать данные из основной памяти в кэш?

StackOverflow https://stackoverflow.com/questions/524821

Вопрос

Итак, меня учат ассемблеру, и у нас есть задание, которое состоит в том, чтобы найти разницу во времени между чтением из памяти и чтением из кэша.Мы должны сделать это, создав 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:

что ж, тогда я не собираюсь совать нос не в свое дело и ценю вашу помощь, у меня просто есть еще один вопрос, поскольку это два цикла, которые я должен выполнить.Мне нужно как-то сравнить их, я искал инструкцию по таймеру, но я не нашел ни одной, я нашел только: Время наступления времени, Полученное количество и Счетчик производительности но, насколько я понимаю, эти инструкции возвращают системное время, а не время, необходимое для завершения цикла.Есть ли способ на самом деле делать то, что я хочу?или мне нужно придумать другой способ?

Кроме того, для чтения из разных регистров во втором цикле (тот, который не считывается из кэша) нормально ли, если я даю различные инструкции "mov"?или я здесь совершенно не прав?

Извините за все эти вопросы, но еще раз спасибо вам за вашу помощь.

Это было полезно?

Решение

Для чтения из кэша.есть цикл, который считывает данные с того же (или очень похожего) адреса памяти:

  • При первом чтении с этого адреса значения с этого адреса памяти (и с другого, близлежащего адреса памяти) будут перемещены в кэш
  • В Далее время, когда вы читаете из этого то же самое адрес, значения уже кэшированы, и поэтому вы читаете из кэша.

Чтобы прочитать некэшированную память, создайте цикл, который считывает данные из многих, очень разных (т.е.дальше друг от друга, чем размер кэша) адреса памяти.


Чтобы ответить на ваш второй вопрос:

  • То, что вы делаете с ecx и jnz, выглядит нормально (я не знаю, насколько точен / чувствителен ваш таймер, но вы можете захотеть выполнить цикл более 100 раз)

  • В mov eax, eax не является "прочитанной памятью" ...это безоперационный режим, который переводит eax в eax.Вместо этого я думаю, что синтаксис MASM для чтения из памяти - это нечто большее, чем mov eax,[esi] ("считайте из ячейки памяти, адрес которой содержится в esi")

  • В зависимости от того, какой O / S вы используете, вы должны считывать данные с адреса памяти, который действительно существует и доступен для чтения.Например, в 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]

...где 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 - это некоторое приращение, равное примерно пятой части длины фрагмента.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top