Масивите, инициализирани като `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, така че имам нужда от подравнена памет, така че въпросът е: имам ли нужда от memalign/_aligned_malloc или моят масив е деклариран като

static float m1[SIZE][SIZE];

вече подравнен? (SIZE е int)


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