Паралелизирам определен проблем с динамично програмиране, използвайки инструкции AVX2/SSE.
В основната итерация на моето изчисление изчислявам колона в матрица, където всяка клетка е структура от AVX2 регистри (_m256i
). Използвам стойности от предишната колона на матрицата като входни стойности за изчисляване на текущата колона. Колоните могат да бъдат големи, така че това, което правя, е да имам масив от структури (в стека), където всяка структура има два _m256i
елемента.
Структура:
struct Cell {
_m256i first;
_m256i second;
};
След това имам масив като този: Cell prevColumn [N]
. N
обикновено ще бъде няколко стотици.
Знам, че _m256i
основно представлява avx2 регистър, така че се чудя как да мисля за този масив, как се държи, след като N е много по-голямо от 16 (което е броят на avx регистрите)? Добра практика ли е да се създаде такъв масив или има някакъв по-добър подход, който трябва да използвам, когато съхранявам много _m256i
стойности, които скоро ще бъдат повторно използвани?
Освен това има ли някакво подравняване, което трябва да направя с тези структури? Четох много за подравняването, но все още не съм сигурен как и кога точно да го направя.
Cell
еSoA
, когато го съхранявате или четете (напр.typedef union __m256i { int8_t m256_i8[32]; int16_t m256_i16[16]; int32_t m256_i32[8]; } __256i;
). Тогава вCell prevColumn [N]
масивътprevColumn
е AoSoA. - person Z boson   schedule 11.05.2015int
или се съхранява в регистър (напр. rdx) или се съхранява в паметта. Компилаторът се грижи за това. Вашият въпрос е аналогичен на въпроса дали е добре да се направи масив отint
s (също има 16 скаларни регистъра точно като 16 YMM регистъра). В паметта можете да мислите за__256i
катоtypedef union __m256i { int8_t m256_i8[32]; int16_t m256_i16[16]; int32_t m256_i32[8]; } __256i;
, ако желаете. - person Z boson   schedule 12.05.2015