Массивы, инициализированные как `float [10] [10]`, уже выровнены по памяти для SIMD / SSE?

Мне нужно оптимизировать умножение матриц с помощью SIMD / Intel SSE. Приведенный пример кода выглядит так:

*x = (float*)memalign(16, size * sizeof(float));

Однако я использую C ++ и [found that][1] I вместо malloc (перед выполнением SIMD) я должен использовать new. Теперь я продолжаю оптимизацию с помощью SIMD / SSE, поэтому мне нужна выровненная память, поэтому вопрос: нужен ли мне _5 _ / _ 6_ или мой массив объявлен как

static float m1[SIZE][SIZE];

уже выровнен? (SIZE - это целое число)


person Jiew Meng    schedule 03.10.2012    source источник


Ответы (1)


Как правило, они не будут выровнены по 16 байт, хотя в спецификации C ++ нет ничего, что могло бы помешать вашему компилятору выровнять такой массив по 16-байтовой границе. В зависимости от того, какой компилятор вы используете, обычно существует специфичный для компилятора способ запросить выравнивание массива по 16-байтовой границе. Например, для gcc вы должны использовать:

static float m1[SIZE][SIZE] __attribute__((aligned(16)));

В качестве альтернативы вы можете использовать posix_memalign(), memalign() или другие API-интерфейсы с выровненным распределением, доступные на вашей платформе, чтобы получить блок памяти с желаемым выравниванием. В худшем случае вы можете даже выделить память, используя стандартные malloc() или operator new, а затем самостоятельно выполнить настройку выравнивания.

person Jason R    schedule 03.10.2012
comment
Я использую g++, я полагаю, это то же самое? Я имею в виду gcc для C, а g++ для C ++? Поскольку я использую C ++, то я делаю это для g++? Я попробую это. - person Jiew Meng; 03.10.2012
comment
Внешний интерфейс gcc фактически поддерживает как C, так и C ++. Он будет переключать режимы в зависимости от расширения исходного файла (т.е. он будет ожидать, что .c файл будет C, а .cc или .cpp файлы будут C ++). Если вы хотите быть C ++ - явным, вы можете вместо этого вызвать его как g++. - person Jason R; 03.10.2012
comment
Также обратите внимание, что SIZE должен быть кратным 4, если вы хотите, чтобы каждая строка массива была выровнена (я предполагаю, что и вы, и OP знают об этом - я просто добавляю его для всех будущих читателей этого вопроса). - person Paul R; 03.10.2012
comment
Хм, теперь мне нужно выделить память в куче ... Думаю, мне нужно будет преобразовать в float* m1 = new float[SIZE*SIZE], как теперь __attribute__((aligned(16))) часть вписывается? - person Jiew Meng; 04.10.2012
comment
Если вы выделяете из кучи, вы должны использовать одну из memalign()-подобных функций, подобных тем, которые вы отметили в своем исходном вопросе. В этом случае вы не захотите использовать operator new, если вы не переопределите его, чтобы выделить базовую память с помощью одного из выровненных средств. - person Jason R; 04.10.2012