Контрольная работа №2 (кр_в), страница 2
Описание файла
Файл "Контрольная работа №2" внутри архива находится в папке "кр_в". Документ из архива "кр_в", который расположен в категории "". Всё это находится в предмете "параллельная обработка данных" из 9 семестр (1 семестр магистратуры), которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "Контрольная работа №2"
Текст 2 страницы из документа "Контрольная работа №2"
3. Программирование с учетом расслоения памяти и выравнивания данных.
Расслоение памяти.
Основное правило при программировании с учетом расслоения памяти – добиться, чтобы потоки данных (блоки памяти) начинались с различных DRAM-банков. Поскольку большинство современных модулей памяти имеет четырехбанковую организацию, то крайне нежелательно обрабатывать более четырех потоков данных параллельно, в противном случае возникают проблемы производительности. В случае если необходимо обрабатывать более четырех потоков данных одновременно, можно прибегнуть к виртуализации потоков данных: создать один физический поток, разбив его на несколько логических (виртуальных) потоков, тем самым используя interleave-трансляцию адресов.
На рисунке показан пример, когда два исходных потоков (слева) сливаются в один физический поток, сконструированный по принципу чередования адресов, что фактически равносильно его расщеплению на два логических потока.
Рисунок 3. Виртуализация потоков данных.
Такая организация работы памяти во-первых, позволяет избежать постоянного открытия/закрытия DRAM-страниц; во-вторых, гарантирует, что смежные ячейки потоков а и b не попадут на различные страницы одного и того же DRAM-банка, находящегося в момент обращения на регенерации. И, в-третьих, облегчает работу системе аппаратной предвыборке (если таковая имеется), поскольку большинство таких систем оптимизированы всего под один поток.
Поскольку переход от физического адреса потока к логическому неизбежен без взятия остатка, необходимо избавиться от машинной команды DIV, выполняющей целочисленное деление, ввиду ее низкой скорости. В частности, если количество потоков соответствует степени двойки, то взятие остатка можно осуществить быстрыми битовыми операциями.
Выравнивание данных.
Если запрошенные данные целиком умещаются в один пакетный цикл, то величина выравнивания не играет никакой роли. Например, чтение двойного слова, начинающегося с адреса 0x40001, осуществляется безо всяких задержек, поскольку оно гарантированно не пересекает пакетный цикл. При линейной обработке памяти кратность выравнивания начального адреса играет второстепенную роль, тем не менее, для достижения максимальной производительности, рекомендуется соответствующим образом выравнивать адреса:
Размер данных | Граница |
1 байтов (8 битов) | Произвольная |
2 байтов (16 битов) | Кратная 2 байтам |
4 байтов (32 бита) | Кратная 4 байтам |
8 байтов (64 битов) | Кратная 8 байтам |
10 байтов (80 битов) | Кратная 16 байтам |
16 байтов (128 битов) | Кратная 16 байтам |
Иная ситуация с записью данных. Механизм отложенной записи, реализованный в современных процессорах, предотвращает падение производительности, вызванное несовпадением размером записываемых данных с границами пакетных циклов. Однако данный эффект наблюдается исключительно при записи данных в оперативную память. Не выровненная запись в кэш-память несет значительные издержки, многократно снижая производительность, поэтому пренебрегать выравниванием допускается только при обработке блоков памяти, многократно превосходящих в объеме емкость кэшей всех уровней.
4. Использование команд управления кэшем.
При грамотном обращении команды управления кэшированием (равно как и аппаратная предвыборка) ускоряют типовые операции с памятью в несколько раз. Впервые программное управление загрузкой строк кэша появилось в составе набора команд AMD 3D Now! в виде инструкции prefetch, позволяющей программисту заблаговременно загружать в кэш ячейки памяти, к которым он рассчитывает обратиться в ближайшем будущем. Причем, загрузка данных осуществляется без участия и остановки вычислительного конвейера. В результате, "ручное" управление кэш-контроллером позволяет выбрать оптимальную стратегию упреждающей загрузки данных, что существенно уменьшает количество кэш-промахов; кроме того, с предвыборкой становится возможным загружать очередную порцию данных параллельно с обработкой предыдущей. Следом за K6, предвыборка появилась и в процессоре Pentium-III вместе с набором команд "ручного" управления кэшированием.
В AMD K6\Athlon программная предвыборка осуществляется одной из двух инструкций prefetch или prefetchw. Суффикс на конце последней сообщает процессору, что загружаемые данные планируется модифицировать. Это не означает, что данные, загружаемые, посредством prefetch, нельзя модифицировать. Модифицировать их можно, но не желательно, т.к. в этом случае процессор вынужден совершать дополнительный цикл, изменяя атрибуты соответствующей кэш-строки с эксклюзивной на модифицируемую:
-
Эксклюзивные, т.е. неизменяемые кэш-строки, при их вытеснении из кэша они просто выбрасываются.
-
Модифицируемые же кэш-строки независимо от того, были ли они реально модифицированы или нет, всегда вытесняются в оперативную память (или кэш вышестоящего уровня), что требует определенного количества тактов процессора.
Инструкция prefetch просто инициирует запрос ячейки памяти, точно так, как это делает любая команда, обращающаяся к памяти, но, в отличие от последней, prefetch не помещает загружаемые данные ни в какой регистр, более того, она вообще не дожидается окончания загрузки этих данных, тут же возвращая управление. Инструкция prefetchw работает аналогично prefetch, но автоматически присваивает загружаемой строке статус модифицируемой. Если строку действительно планируется модифицировать, это сэкономит несколько десятков тактов процессорного времени. Однако, если неизвестно, будет ли реально модифицирована строка, или нет, то лучше загрузить ее как эксклюзивную, т.к. выгрузка модифицируемой, но реально не модифицированной строки в оперативную память обойдется намного дороже.
В процессорах Intel Pentium программная предвыборка осуществляется следующими инструкциями: prefetchnta, prefetcht0, prefetcht1, prefetcht2. Суффикс указывает на тип загружаемых данных, что определяет уровень кэш-иерархии, в которую эти данные будут загружены. Так, "NTA" расшифровывается как "Non-TemporAl [Data]" – не временные данные, т.е. данные, многократное использование которых не планируется. Соответственно "T0", "T1" и "T2" обозначает временные данные, использовать которые планируется неоднократно.
Какой бы командной предвыборка ни осуществлялась, кэш-линейкам, загружаемым из основной памяти, всегда присваивается эксклюзивный статус. При предвыборке линеек из кэша второго уровня, их прежний статус сохраняется. Возможность загрузки кэш-линейки с автоматической установкой статуса модифицируемой в процессорах Pentium не реализована. Причем, в отличие от prefetch/w, инструкции prefetchnta/t0/t1/t2 не приказывают, а рекомендуют осуществить предвыборку.
Дополнительный вопрос.
Рекомендации по оптимальному управлению памятью при программировании.
-
Разворачивать циклы, читающие память; для циклов, пишущих в память, развертка может приводить к различным результатам; смешанные циклы также рекомендуется разворачивать;
-
Устранять зависимости по данным. При обработке независимых данных пагубное влияние латентности подсистемы памяти в значительной мере ослабляется, и производительность определяется исключительно пропускной способностью.
-
Отправлять контроллеру памяти несколько запросов одновременно, запрашивать данные на чтение с шагом не меньшим 32 байт. Поскольку минимальной порцией обмена с памятью является не байт, а пакет, длина которого варьируется от 32 до 128 байт, то имеет смысл в первом проходе цикла читать ячейки с шагом, кратным размеру пакета, а оставшиеся ячейки обрабатывать как обычно.
-
Обращаться как можно к меньшему количеству страниц, т.е. в пределах одной страницы располагайте данные максимально плотно, не оставляя пустот. Причем, страницы должны запрашиваться в порядке возрастания их линейных адресов.
-
Виртуализировать потоки данных, объединяя несколько логических потоков памяти в один физический.
-
Обрабатывать данные двойными словами: чтение памяти лучше всего осуществлять двойными словами, а запись – либо байтами, либо двойными словами.
-
Выравнивать адрес источников данных. Не выровненный адрес источника приводит к заметному падению производительности операции чтения.
-
Комбинировать вычисления с доступом к памяти. Это позволяет более полно загружать конвейер процессора.
-
Обращаться к памяти только тогда, когда это действительно необходимо.
-
Не оптимизировать программу на отдельно взятой машине