Następujące pytanie związane jest jednak odpowiedzi są stare, i komentarz od użytkownika Marc Glisse sugeruje nowych podejść od C ++ 17 do tego problemu, które nie mogą być należycie rozpatrzone.
Próbuję uzyskać wyrównaną pamięć działającą poprawnie dla SIMD, wciąż mając dostęp do wszystkich danych.
W przypadku Intela, jeśli utworzę wektor zmiennoprzecinkowy typu __m256
i zmniejszy mój rozmiar 8-krotnie, otrzymam wyrównaną pamięć.
Na przykład std::vector<__m256> mvec_a((N*M)/8);
W nieco zhakowany sposób mogę rzutować wskaźniki na elementy wektorowe w celu unoszenia się na powierzchni, co pozwala mi na dostęp do poszczególnych wartości zmiennoprzecinkowych.
Zamiast tego wolałbym mieć std::vector<float>
poprawnie wyrównany, a zatem może być ładowany do __m256
innych typów SIMD bez segfault.
Patrzyłem na wyrównany_alloc .
To może dać mi tablicę w stylu C, która jest poprawnie wyrównana:
auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));
Nie jestem jednak pewien, jak to zrobić std::vector<float>
. Przekazanie std::vector<float>
własności marr_a
nie wydaje się możliwe .
Widziałem kilka sugestii, że powinienem napisać niestandardowy alokator , ale wydaje się, że to dużo pracy, a może w nowoczesnym C ++ jest lepszy sposób?
_mm256_loadu_ps(&vec[i])
. (Chociaż uwaga, że przy domyślnych opcjach tuningu, GCC dzieli nie gwarantowanych wyrównany 256-bitowe Obciążenia / sklepy w vmovups xmm / vinsertf128. Więc nie jest zaletą przy użyciu_mm256_load
ponadloadu
jeśli dbasz o to jak kompiluje kod na GCC, jeśli ktoś zapomni użycie-mtune=...
lub-march=
opcje.)