Ho spesso bisogno di allineare l'inizio di una matrice dinamica a un limite di 16, 32 o 64 byte per la vettorizzazione, ad es. Per SSE, AVX, AVX-512. Sto cercando un modo trasparente e sicuro per utilizzarlo in combinazione con i puntatori intelligenti, in particolare std::unique_ptr
.Array dinamico e puntatore intelligente allineati
Dato un implementazione di allocazione e deallocazione routine, dicono
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);
}
};
mi piacerebbe fare qualcosa di simile
std::unique_ptr<float[]> data(allocate_aligned<float>(alignment, length));
ma non riuscivo a capire come si ottiene unique_ptr
di utilizzare la corretto Deleter
senza richiedere all'utente di specificarlo (che è una potenziale causa di errori). L'alternativa che ho trovato è stato quello di utilizzare un modello alias
template<class T>
using aligned_unique_ptr = std::unique_ptr<T[], DeleteAligned<T>>;
Poi possiamo usare
aligned_unique_ptr<float> data(allocate_aligned<float>(alignment, length));
Il restante problema è che nulla mantiene l'utente di mettere il puntatore del grezzo in un std::unique_ptr
.
A parte questo, vedi qualcosa di sbagliato in questo? Esiste un'alternativa meno incline agli errori, ma completamente trasparente per l'utente dopo che è stata effettuata l'allocazione?
Vale la pena ricordare che questo è essenzialmente ciò che 'std :: make_unique' sta facendo per' new' in C++ 14. –
@KonradRudolph Buon punto, modificato in. – Angew