Często potrzebuję wyrównać początek tablicy dynamicznej do granicy 16, 32 lub 64 bajtów dla wektorowania, np. Dla SSE, AVX, AVX-512. Szukam przejrzystego i bezpiecznego sposobu użycia tego w połączeniu z inteligentnymi wskaźnikami, w szczególności std::unique_ptr
.Wyrównana tablica dynamiczna i inteligentny wskaźnik
Biorąc pod uwagę wdrożenie rozdziału i dealokacji rutyny, powiedzmy
template<class T>
T * allocate_aligned(int alignment, int length)
{
// omitted: check minimum alignment, check error
T * raw = 0;
// using posix_memalign as an example, could be made platform dependent...
int error = posix_memalign((void **)&raw, alignment, sizeof(T)*length);
return raw;
}
template<class T>
struct DeleteAligned
{
void operator()(T * data) const
{
free(data);
}
};
chciałbym zrobić coś takiego
std::unique_ptr<float[]> data(allocate_aligned<float>(alignment, length));
ale nie mogłem dowiedzieć się, jak dostać unique_ptr
używać właściwy Deleter
bez konieczności podawania przez użytkownika (co jest potencjalną przyczyną błędów). Alternatywą znalazłem użyć szablonu alias
template<class T>
using aligned_unique_ptr = std::unique_ptr<T[], DeleteAligned<T>>;
Wtedy możemy użyć
aligned_unique_ptr<float> data(allocate_aligned<float>(alignment, length));
Pozostałą problemem jest to, że nic nie trzyma użytkownikowi wprowadzenie surowego wskaźnik do std::unique_ptr
.
Czy widzisz coś nie tak z tym? Czy istnieje alternatywa, która jest mniej podatna na błędy, ale całkowicie przejrzysta dla użytkownika po dokonaniu alokacji?
Warto wspomnieć, że jest to zasadniczo to, co robi 'std :: make_unique' dla' new' w C++ 14. –
@KonradRudolph Dobry punkt, redagowany w. – Angew