Потребление энергии относительно физического размера электронного оборудования увеличилось, поскольку компоненты стали меньше и более плотно упакованы. В сочетании с высокими рабочими частотами это привело к неприемлемым уровням рассеивания мощности. На память приходится большая доля потребляемой мощности, и этот вклад может быть уменьшен путем оптимизации организации данных — способа хранения данных. [1]
Оптимизация мощности в электронных системах с высокой плотностью памяти стала одной из основных проблем для таких устройств, как мобильные телефоны , встроенные системы и беспроводные устройства. По мере увеличения числа ядер на одном чипе увеличивается и потребление энергии устройствами. Исследования распределения энергопотребления в смартфонах и центрах обработки данных показали, что подсистема памяти потребляет около 40% от общей мощности. В серверных системах исследование показывает, что память потребляет примерно в 1,5 раза больше энергии, чем ядро. [2]
Шины системного уровня, такие как шины вне чипа или длинные шины на чипе между IP-блоками, часто являются основными источниками потребления энергии из-за их большой емкости нагрузки. Экспериментальные результаты показали, что активность шины для доступа к памяти может быть снижена до 50% путем организации данных. Рассмотрим случай компиляции кода, написанного на языке программирования C :
целое А [ 4 ][ 4 ], В [ 4 ][ 4 ]; для ( i = 0 ; i < 4 ; i ++ ) { для ( j = 0 ; j < 4 ; j ++ ) { B [ i ][ j ] = A [ j ][ i ]; } }
Большинство существующих компиляторов C размещают многомерный массив в строчной форме, то есть строка за строкой: это показано в столбце «неоптимизировано» в соседней таблице. В результате, при запуске этого кода нет доступа к памяти, поскольку доступ к элементам в столбцах осуществляется последовательно. Но можно изменить способ, которым они размещаются в памяти, чтобы максимизировать количество последовательных доступов из памяти. Этого можно достичь, упорядочив данные, как показано в столбце «оптимизировано» таблицы. Такое перераспределение данных компилятором может значительно снизить потребление энергии из-за доступа к памяти. [3]
неоптимизированный | оптимизированный |
---|---|
А[0][0] | А[0][0] |
А[0][1] | Б[0][0] |
А[0][2] | А[1][0] |
А[0][3] | Б[0][1] |
А[0][0] | А[2][0] |
А[1][0] | Б[0][2] |
А[1][1] | А[3][0] |
. | Б[0][3] |
. | А[0][1] |
Б[0][0] | Б[1][0] |
Б[0][1] | А[1][1] |
Б[0][2] | Б[1][1] |
Б[0][3] | . |
Б[1][0] | . |
. | . |
. | А[3][3] |
Б[3][3] | Б[3][3] |
Этот метод включает в себя преобразования исходного кода , которые либо изменяют структуру данных, включенную в исходный код, либо вводят новые структуры данных или, возможно, изменяют режим доступа и пути доступа с целью снижения энергопотребления. Для выполнения таких преобразований используются определенные методы.
Основная идея заключается в изменении порядка объявления локального массива , так что массивы, к которым чаще всего обращаются, размещаются на вершине стека таким образом, что к часто используемым ячейкам памяти осуществляется прямой доступ. Для достижения этого объявления массивов реорганизуются так, чтобы поместить сначала массивы, к которым чаще всего обращаются, что требует либо статической оценки, либо динамического анализа частоты доступа к локальным массивам.
В любой вычислительной программе локальные переменные хранятся в стеке программы, а глобальные переменные хранятся в памяти данных. Этот метод включает преобразование локальных массивов в глобальные массивы, чтобы они хранились в памяти данных, а не в стеке. Местоположение глобального массива может быть определено во время компиляции, тогда как местоположение локального массива может быть определено только при вызове подпрограммы и зависит от значения указателя стека. Как следствие, доступ к глобальным массивам осуществляется в режиме адресации смещения с константой 0, в то время как доступ к локальным массивам, за исключением первого, осуществляется с константой смещения, отличной от 0, и это обеспечивает снижение энергопотребления.
В этом методе элементы, к которым осуществляется доступ чаще всего, определяются с помощью профилирования или статических соображений. Копия этих элементов затем сохраняется во временном массиве, к которому можно получить доступ без каких-либо промахов кэша данных. Это приводит к значительному снижению энергопотребления системы, но также может снизить производительность. [1]
Встроенные кэши используют статическую оперативную память , которая потребляет от 25% до 50% от общей мощности чипа и занимает около 50% от общей площади чипа. Память Scratchpad занимает меньшую площадь, чем встроенные кэши. Это обычно снижает потребление энергии блоком памяти, поскольку меньшая площадь подразумевает снижение общей коммутируемой емкости. Современные встроенные процессоры, особенно в области мультимедийных приложений и графических контроллеров, имеют встроенную память Scratchpad. В системах кэш-памяти отображение элементов программы выполняется во время выполнения, тогда как в системах Scratchpad памяти это делается либо пользователем, либо автоматически компилятором с использованием подходящего алгоритма. [4]