Как мы можем указать физический адрес для переменной?

Любые предложения/обсуждения приветствуются!

Вопрос на самом деле краток, как заголовок, но я объясню, зачем мне нужен физический адрес.


Фон:

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

В некоторых моделях ЦП (например, в моем Intel Core Duo T5800) кэш L2 распределяется между ядрами. Итак, если программа A обращается к памяти по физическому адресу, например

0x00000000, 0x20000000, 0x40000000...

и программа B получает доступ к данным в

0x10000000, 0x30000000, 0x50000000...

Поскольку эти адреса имеют один и тот же суффикс, соответствующий набор в кэше L2 будет часто очищаться. И мы ожидаем увидеть две программы, борющиеся друг с другом, медленно считывающие данные из памяти, а не из кеша, хотя и разнесенные по разным ядрам.

Потом хочу проверить результат на практике. В этом эксперименте мне нужно знать физический адрес, а не виртуальный адрес. Но как мне справиться с этим?


Первая попытка:

Съешьте большое пространство из кучи, замаскируйте и получите определенный адрес.

Мой ЦП имеет кеш L2 с размером = 2048 КБ и ассоциативностью = 8, поэтому физические адреса, такие как 0x12340000, 0x12380000, 0x123c0000, будут связаны с первым набором в кеше L2.

int HEAP[200000000]={0};
int *v[2];
int main(int argc, char **argv) {

    v[0] = (int*)(((unsigned)(HEAP)+0x3fffc) & 0xfffc0000);
    v[1] = (int*) ((unsigned)(v[0]) + 0x40000); 

    // one program pollute v[0], another polluting v[1]
}

К сожалению, с «помощью» виртуальной памяти переменная HEAP не всегда непрерывна внутри физической памяти. v[0] и v[1] могут быть связаны с разными наборами кеша.


Вторая попытка

получить доступ к /proc/self/mem и попытаться получить информацию о памяти.

Хм... кажется, что результаты все еще касаются виртуальной памяти.


person sleepsort    schedule 19.12.2012    source источник
comment
Я не думаю, что вы можете указать физический адрес, по крайней мере, без изменений ядра. Но вы можете ЗНАТЬ физические адреса на массовом уровне, используя /proc/self/maps   -  person anishsane    schedule 19.12.2012
comment
@anishsane хм, я сбросил /proc/self/maps, но как это связано с физическими адресами? Первое поле похоже на виртуальный адрес, так связано ли поле dev с запоминающим устройством?   -  person sleepsort    schedule 19.12.2012
comment
о, извините, да, первые 2 поля действительно являются виртуальными адресами ... Я использовал его, чтобы получить некоторые виртуальные адреса, соответствующие физическим адресам панели PCI-устройства, которое я открываю ... извините за введение в заблуждение ...   -  person anishsane    schedule 19.12.2012
comment
Работать на уровне физических адресов на современных настольных процессорах непросто. На маленьких микроконтроллерах легко программировать на ассемблере, но вы не увидите эффектов кеша (те, которые я знаю, не имеют кеша).   -  person Peter G.    schedule 19.12.2012


Ответы (1)


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

В контексте процессов пользовательского режима почти каждый адрес, который вы видите, является виртуальным адресом< /сильный>. То есть адрес, который имеет смысл только в контексте этого процесса. ОС управляет отображением того, где это пространство виртуальной памяти (уникальное для процесса) отображается на страницы памяти. Эти страницы памяти в любой момент времени могут сопоставляться со страницами, которые выгружаются (т. е. находятся в физической оперативной памяти) или они могут быть выгружены и существовать только в файле подкачки на диске.

Таким образом, в примере с Background эти адреса принадлежат двум разным процессам, поэтому попытка сравнить их абсолютно ничего не значит. Присутствует ли их код в каком-либо из кешей, зависит от ряда факторов, в том числе от замены кеша. стратегия процессора, политики кэширования, разрешенные ОС, количество других процессов (включая потоки режима ядра) и т. д.

В вашей первой попытке, опять же, вы не добьетесь ничего, кроме непосредственного тестирования кеша ЦП. Прежде всего, ваш большой буфер не будет находиться в куче. Он будет частью раздела данных (в частности, .bss) исполняемого файла. Куча используется для семейства malloc() распределения памяти. Во-вторых, на самом деле не имеет значения, выделяете ли вы какой-то огромный регион размером 1 ГБ, потому что, хотя он является непрерывным в виртуальном адресном пространстве вашего процесса, ОС должна распределять страницы виртуальной памяти там, где она считает нужным, что может < em>не на самом деле быть смежным. Опять же, у вас практически нет контроля над выделением памяти из пользовательского пространства. "Есть ли способ выделить непрерывную физическую память из пользовательского пространства в Linux?" Краткий ответ: нет.

/proc/$pid/maps тоже ни к чему не приведет. Да, там перечислено множество адресов, но опять же, все они находятся в виртуальном адресном пространстве процесса $pid. Еще немного информации об этом: Как читать из /proc/$pid/mem под Linux?

person Jonathon Reinhart    schedule 19.12.2012
comment
Вы правы, если мы просто попытаемся получить доступ к одному адресу, он может быть отправлен другому процессу. Однако я пытаюсь получить доступ к физическому адресу определенного типа (например, 0x????0000). Будет полезно, если мы будем знать, какая позиция в большом массиве соответствует нашему условию. - person sleepsort; 19.12.2012
comment
Я пытаюсь получить доступ к определенному типу физического адреса Нет. Любой адрес, к которому вы пытаетесь получить доступ из пользовательской программы, не является физическим адресом. Это виртуальный адрес, и вы не представляете, где он будет отображаться в физическом адресном пространстве. - person Jonathon Reinhart; 19.12.2012
comment
Хм, когда у нас будет достаточно ресурсов (например, более 2 ядер, много памяти), можем ли мы предположить, что ОС не будет выгружать/переназначать страницы, и среда будет достаточно стабильной? - person sleepsort; 19.12.2012
comment
Количество ядер не имеет ничего общего с подкачкой/выгрузкой памяти. На самом деле, большее количество ядер ЦП может повысить более вероятность выгрузки процесса. Конечно, если у вас бесконечная оперативная память, то использование вашего раздела подкачки будет практически нулевым. Но что это дает вам? Если вы хотите посмотреть на производительность кеша, вы можете просто замерить время выполнения некоторого кода в цикле в первый раз и сравнить его с последующими итерациями. - person Jonathon Reinhart; 19.12.2012
comment
Этот вопрос становится все более и более не по теме. На самом деле это теоретические вопросы, на которые можно было бы гораздо лучше ответить, проведя некоторые исследования и прочитав о том, как работают виртуальная память, кэши и т. Д. Похоже, что здесь нет реальной проблемы программирования. - person Jonathon Reinhart; 19.12.2012