Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Аппаратное обеспечение

Что каждый программист должен знать о памяти. Часть 8. Технологии будущего

Оригинал: Memory part 8: Future technologies
Автор: Ulrich Drepper
Дата публикации: ноябрь 2007 г.
Перевод: М.Ульянов
Дата перевода: май 2010 г.

8. Грядущие технологии: что нас ждет?

8.4. Векторные операции

Мультимедийные расширения современных процессоров, по сути, реализуют векторные операции в некоторой, очень ограниченной форме. Векторные инструкции характеризуются большим числом операций, выполняемых вместе. Ну, большим - если говорить о мультимедиа инструкциях и сравнивать со скалярными операциями. Это тем не менее очень и очень далеко от векторных компьютеров вроде Cray-1 или векторных блоков комплекса IBM 3090.

Для компенсации ограниченного числа операций, выполняемых за одну инструкцию (на большинстве машин это четыре операции с типом float или две с double), необходимо увеличение количества итераций внешних циклов. Пример в разделе 9.1 ясно это показывает: на каждую кэш-строку приходится по SM итераций.

Уменьшить это число можно, расширив векторные регистры и операции. Это дает нам нечто большее, чем просто улучшение декодирования инструкций и т.п.; мы сейчас более заинтересованы во влиянии на память. Если одной инструкцией можно считывать или записывать больше данных, то процессору лучше видно, как приложение использует память, и не приходится собирать информацию по кусочкам, исследуя поведение множества отдельных инструкций. Далее, полезнее становятся инструкции "сквозного" чтения или записи, т.е. которые не трогают кэш. С размером SSE регистра в 16 байт (в процессоре x86), использование "сквозного" чтения - не лучшая идея, поскольку тогда последующие запросы к той же строке будут вынуждены по новой загружать данные из памяти (в случае промахов кэша). С другой стороны, если векторные регистры будут достаточного размера для хранения одной и более строк кэша, операции сквозного чтения/записи станут не так страшны. На практике растет необходимость работать с наборами данных, не помещающимися в кэш-память.

Наличие больших векторных регистров не обязательно означает увеличение латентности, ведь векторным инструкциям не нужно ждать, пока прочитаются/запишутся все данные. Векторные процессорные блоки могут начать работу с теми данными, которые уже успели загрузиться, если получится распознать кодовую последовательность. Это значит, например, что если нужно загрузить векторный регистр и затем все элементы умножить на некое число, то процессор может начать операцию перемножения как только первая часть вектора будет загружена, не дожидаясь загрузки остальных. Всё это лишь вопрос сложности векторного блока. Рассмотренные факты показывают, что теоретически векторные регистры могут распространиться очень широко и уже сегодня программы можно разрабатывать, учитывая данную возможность. Практически же, процессоры используются в многопроцессных и многопоточных операционных системах, что накладывает ограничения на размер векторных регистров. А именно, важно время контекстного переключения, куда входит сохранение/загрузка значений регистров.

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

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

  • используя striding, он же интервальный режим, можно указать величину промежутка между двумя соседними векторными элементами. Интервалы между всеми элементами должны быть одинаковыми, но это, к примеру, легко позволяет считать столбец матрицы в векторный регистр за одну инструкцию, а не использовать по инструкции на каждую строку.
  • используя косвенную адресацию памяти, можно создавать шаблоны произвольного доступа. Инструкция чтения/записи получает указатель на массив с адресами или смещениями от адресов памяти, и по ним работает.

Сейчас еще не ясно, увидим ли мы возрождение настоящих векторных операций в процессорах будущего. Быть может, эта задача будет возложена на сопроцессоры. В любом случае, если мы получим доступ к векторным операциям, будет важно корректно организовывать код, выполняющий подобные операции. Код должен быть самодостаточным и заменяемым, с интерфейсом, позволяющим эффективно применять векторные операции. Например, интерфейсы должны обеспечивать добавление матриц целиком, вместо того чтобы ограничиваться строками, столбцами или даже группами элементов. Чем больше "строительные блоки", тем выше шанс использования векторных операций.

В [vectorops] авторы призывают к возрождению векторных операций. Они выделяют множество преимуществ и пытаются развеять некоторые мифы. Но по правде говоря, они рисуют слишком упрощенную картину. Выше упомянуто, что большие наборы регистров означают увеличение времени контекстных переключений, чего следует избегать в операционных системах общего назначения. Почитайте о проблемах процессора IA-64, возникающих при операциях, интенсивно применяющих контекстные переключения. Долгое время выполнения векторных операций также становится проблемой, если задействуются прерывания. При возникновении прерывания, процессор должен остановить текущую работу и обработать его. После этого можно возобновлять прерванную работу. А в целом, прервать выполнение инструкции где-то в середине достаточно сложно; не то чтобы совсем невозможно, но сложно. Если время выполнения инструкции велико, то в ней должна быть реализована возможность приостановки, либо перезапуска. Иначе время реагирования на прерывание станет слишком большим. Последнее - недопустимо.

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


  Вся часть 8 в одном файле  
Замечания и предложения по переводу принимаются по адресу michael@right-net.ru. М.Ульянов.

Назад Оглавление Вперед