2014-01-24 2 views
1

Мы знаем, что существуют уровни в иерархии памяти, кеш , первичное хранилище и вторичное хранилище. Можем ли мы использовать программу c для выборочного хранения переменной в определенном блоке в иерархии памяти?Как выборочно хранить переменную в сегментах памяти, используя C?

+0

ваши комментарии указывают, что вы спрашиваете о чем-то совершенно другом *. так что ... в чем вопрос? –

ответ

1

Читайте ваши комментарии в других ответах, я хотел бы добавить несколько вещей.

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

Несмотря на это, вы можете сделать что-то, что МОЖЕТ помочь вам приблизиться к тестированию времени доступа в кеше (в основном L1, в зависимости от вашего тестового алгоритма) и в ОЗУ.

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

Для проверки основной памяти (aka RAM): отключите кэш-память в BIOS и запустите свой код.

Для тестирования вторичной памяти (aka disk): отключить кеш диска для данного файла (вы можете попросить об этом свою операционную систему, просто Google об этом) и начать чтение некоторых данных с диска, всегда из такое же положение. Это может работать или не работать в зависимости от того, насколько ваша ОС позволит вам отключить кеш диска (Google об этом).

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

Надеюсь, я помог.

0

Не совсем. Кэш предназначен для прозрачной работы. Почти все, что вы делаете, закончится в кеше, потому что в данный момент он работает.

Что касается вторичного хранилища, я предполагаю, что вы имеете в виду HDD, файл, облако и т. Д. Ничто никогда не будет храниться там, если вы не сделаете это явно, или не настройте область с отображением памяти, или что-то не будет выгружено на диск.

+0

Ну, я хотел рассчитать время доступа для переменных, хранящихся в разных сегментах памяти. Есть ли косвенный способ сделать это? –

0

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

Это говорит о том, что есть профилировщики кэша (например, инструмент Valgrind massif), который дает вам представление о том, насколько хорошо ваша программа использует данный тип архитектуры кеша (а также спекулятивное выполнение) и которая может быть очень полезной для помощи вы обнаруживаете коды кода, которые имеют низкую производительность кеша. Они делают это по существу , имитируя аппаратное обеспечение.

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

+0

Ну, я хотел рассчитать время доступа для переменных, хранящихся в разных сегментах памяти. Есть ли косвенный способ сделать это? –

+0

Насколько мне известно. Возможно, вы можете сделать две версии алгоритма, и один из них агрессивно загрязняет кеш и видит, имеет ли это заметную разницу. –

+0

Да, я думал об этом .. но компилятор C ограничивает размер массива, я не могу заполнить кеш-код этого –

0

Это зависит от конкретной архитектуры и компилятора, которые вы используете.

Например, на x86/x64 большинство компиляторов имеют множество уровней инструкций предварительной выборки, которые указывают на CPU , что кэш-строка должна быть перемещена на определенный уровень в кеше из DRAM (или из более высокопроизводительных, заказывать кеши - например, от L3 до L2).

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

В общем, между L1 и L2 (или L3, или L4 или DRAM) это немного черное отверстие. Вы не можете точно сохранить значение в одном из них - некоторые кеши включают друг в друга (поэтому, если значение находится в L1, оно также находится в L2 и L3), некоторые из них не являются. И кеши предназначены для периодического слива - поэтому, если запись идет на L1, в конечном итоге она работает на L2, затем L3, затем DRAM - особенно в многоядерных архитектурах с сильными модулями памяти.

Вы можете полностью обходить их при записи (используйте потоковое хранилище или отметьте память как объединение записи).

Вы можете измерить различные времена доступа по:

  • Использование памяти файлов, отображенные в качестве резервного хранилища для ваших данных (это будет измерять время для первого доступа доступа к процессору - просто оберните его в вызове таймера, например QueryPerformanceCounter или __rdtscp). Обязательно откройте и закройте файл из памяти между каждым тестом и отключите любое кэширование. Это займет некоторое время.
  • Промывка кеша между доступом для получения времени доступа к DRAM.

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

Это будет сложно сделать в системе с использованием коммерческой ОС, потому что они, как правило, много работают, что будет мешать вашим измерениям.

Смежные вопросы