Расположение памяти MASM32

Asked
Viewd2417

1

Я пытаюсь читать из основной памяти, используя сборку masm32, и для этого я создал (как ранее рекомендовалось в ответе на другой из моих вопросов здесь) массив, который будет содержать сильно разделенные участки памяти (чтобы избегать чтения из кеша). Мне удалось создать массив и прочитать его, однако у меня проблема. Этот массив, который я уже сделал и протестировал, работает с данными, которые я ему предоставил (т.е. числами), и все работает. Но мне нужны места в памяти, и я нигде не могу найти карту или ссылки на них. То есть мне нужно что-то вроде:

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

но вместо чисел я должен использовать соответствующие зарезервированные слова в памяти. Но я не могу их найти = (или даже не знаю, что еще искать.


Позвольте мне просто проверить, правильно ли я понял, а затем вы скажете мне, что я могу (вместо использования массива использовать переменные со всем пробелом между ними, чтобы принудительно читать из основной памяти, верно?

2 ответов

0

Это массив (смежных) байтов, как вы сказали:

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

Это переменная, которая занимает 10 МБ (что много по сравнению с кешем ЦП):

 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. Последовательное чтение для нескольких размеров .

  • Thanks (I’ve forgotten most of MASM). The DUP(?) means don’t initialize it to anything in particular, so I don’t know if it will take space in the executable.

    ChrisW15 февраля 2009, 05:31
  • I’m not familiar with how MASM builds its object files, but those spacers could make your obj file pretty big. You could do the same using the ‘org’ statement to put each variable at a different address.

    Nathan Fellman15 февраля 2009, 05:14
0

Косвенный доступ к памяти в сборке

Чтобы обрабатывать байты в массиве как адреса памяти, вам нужно будет загрузить их в регистр, который может служить базовым адресом, а затем получить доступ к памяти, указанной регистром:

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

О кешах

Обратите внимание, что ваш кеш, вероятно, намного больше, чем диапазон адресов памяти, охватываемых этим массивом, поэтому все они поместятся в кеш.

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

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


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

Моя программа, однако, была не самым эффективным способом сделать это, а также мало намекала на ассоциативность кеша (мне пришлось бы измерить это отдельно, зная схему окраски). Однако оба были выполнены довольно эффективно и относительно независимым от архитектуры способом с помощью нескольких продуманных приемов в SIGMETRICS 2005, работа Ларри Маквоя и Карла Сталина .