Следующий вопрос связан, однако ответы на старые, и комментарий от пользователя Marc Glisse предполагает , что есть новые подходы , начиная с C ++ 17 к решению этой проблемы , которые не могут быть адекватно обсуждены.
Я пытаюсь выровнять память, работающую правильно для SIMD, при этом все еще имея доступ ко всем данным.
В Intel, если я создаю вектор типа float __m256
и уменьшаю свой размер в 8 раз, это дает мне выровненную память.
Например std::vector<__m256> mvec_a((N*M)/8);
Немного хакерским способом я могу приводить указатели на векторные элементы для плавания, что позволяет мне получать доступ к отдельным значениям плавания.
Вместо этого я бы предпочел иметь std::vector<float>
правильно выровненный, и, следовательно, может быть загружен в __m256
и другие типы SIMD без segfaulting.
Я искал в align_alloc .
Это может дать мне массив в стиле C, который выровнен правильно:
auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));
Однако я не уверен, как это сделать std::vector<float>
. Предоставление std::vector<float>
владения marr_a
не представляется возможным .
Я видел несколько предложений о том, что мне следует написать собственный распределитель , но это похоже на большую работу, и, возможно, с современным C ++ есть лучший способ?
_mm256_loadu_ps(&vec[i])
. (Несмотря на то, обратите внимание , что с параметрами настройки по умолчанию, GCC расщепляется не гарантируемой выровнен 256-битовые нагрузок / магазинов в vmovups XMM / vinsertf128. Так что это преимущество для использования_mm256_load
более ,loadu
если вы заботитесь о том , как ваш код компилируется на GCC если кто - то забывает использовать-mtune=...
или-march=
варианты.)