Häufig muss ich den Anfang eines dynamischen Arrays an eine 16, 32 oder 64 Byte Grenze für die Vektorisierung ausrichten, z. B. für SSE, AVX, AVX-512. Ich suche nach einer transparenten und sicheren Möglichkeit, dies in Verbindung mit intelligenten Zeigern zu verwenden, insbesondere std::unique_ptr
.Ausgerichtetes dynamisches Array und intelligenter Zeiger
eine Implementierung von Zuweisung und Freigabe-Routinen gegeben, sagen
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);
}
};
ich so etwas wie dieses
std::unique_ptr<float[]> data(allocate_aligned<float>(alignment, length));
tun möchte, aber ich konnte nicht herausfinden, wie unique_ptr
zu tun bekommen das verwenden richtige Deleter
, ohne vom Benutzer zu verlangen, es zu spezifizieren (was eine mögliche Ursache für Fehler ist). Die Alternative war ich fand eine Vorlage Alias verwenden
template<class T>
using aligned_unique_ptr = std::unique_ptr<T[], DeleteAligned<T>>;
Dann können wir
aligned_unique_ptr<float> data(allocate_aligned<float>(alignment, length));
Das verbleibende Problem verwenden ist, dass nichts den Benutzer davon ab, den rohen Zeiger in einen std::unique_ptr
hält.
Abgesehen davon, sehen Sie irgendetwas falsch damit? Gibt es eine Alternative, die weniger fehleranfällig ist, aber für den Benutzer nach der Zuweisung vollständig transparent ist?
Es ist vielleicht erwähnenswert, dass dies im Wesentlichen das ist, was 'std :: make_unique' in' 'new' 'in C++ 14 macht. –
@KonradRudolph Guter Punkt, bearbeitet in. – Angew