2010-01-08 5 views
12

Gibt es eine Möglichkeit, die STL-Containerausrichtung auf ein bestimmtes Byte zu erzwingen, indem Attribut ((ausgerichtet)) vielleicht? Die Zielcompiler sind nicht Microsoft Visual C++.C++ STL-Datenstrukturausrichtung, Algorithmusvektorisierung

Welche Bibliotheken, wenn überhaupt, spezielle Schablonen von STL-Algorithmen bereitstellen, die eine spezifische explizite Vektorisierung aufweisen, z. SSE. Meine Compiler von Interesse sind g ++, Intel und IBM XL.

Antwort

12

Mit STL-Containern können Sie Ihren eigenen Zuordner über einen optionalen Vorlagenparameter bereitstellen. Ich würde nicht empfehlen, einen gesamten Zuordner von Grund auf neu zu schreiben, aber Sie könnten einen schreiben, der nur ein Wrapper um new und delete ist, aber stellt sicher, dass der zurückgegebene Speicher Ihre Ausrichtungsbedingung erfüllt. (ZB wenn Sie n Bytes mit 16-Byte-Ausrichtung benötigen, verwenden Sie newn + 15 Bytes zuzuweisen und einen Zeiger auf die ersten 16-Byte-ausgerichtete Adresse in diesem Block zurückzukehren.)

Aber es könnte genug sein, um hinzuzufügen, das Alignment-Attribut zum Elementtyp. Das liegt außerhalb des Anwendungsbereichs des Standards. Sie müssen also Ihre Compiler-Dokumentation überprüfen und ausprobieren.

2

Sie benötigen einen benutzerdefinierten Zuordner, der ausgerichteten Speicher zurückgibt. Das sollte dein Problem lösen.

7

Sie müssen einen benutzerdefinierten Zuordner übergeben. Sie können ganz einfach einen über den std::allocator bauen:

template <typename T, size_t TALIGN=16, size_t TBLOCK=8> 
class aligned_allocator : public std::allocator<T> 
{ 
public: 
    aligned_allocator() {} 
    aligned_allocator& operator=(const aligned_allocator &rhs){ 
     std::allocator<T>::operator=(rhs); 
     return *this; 
    } 

    pointer allocate(size_type n, const void *hint){ 
     pointer p = NULL; 
     size_t count = sizeof(T) * n; 
     size_t count_left = count % TBLOCK; 
     if(count_left != 0) 
     { 
      count += TBLOCK - count_left; 
     } 
     if (!hint) 
     { 
      p = reinterpret_cast<pointer>(aligned_malloc(count,TALIGN)); 
     }else{ 
      p = reinterpret_cast<pointer>(aligned_realloc((void*)hint,count,TALIGN)); 
     } 
     return p; 
    } 

    void deallocate(pointer p, size_type n){ 
     aligned_free(p); 
    } 

    void construct(pointer p, const T &val){ 
     new(p) T(val); 
    } 

    void destroy(pointer p){ 
     p->~T(); 
    } 
}; 

Das einzige, was hier fehlt, ist die aligned_malloc, aligned_realloc und aligned_free. Sie müssen sie entweder selbst implementieren (sollte nicht so schwer sein), oder finden Sie Versionen von denen im Internet (Ich habe mindestens eine in OGRE Motor gesehen).

+1

@Anycorn, hast du das jemals umgesetzt? Es scheint, als wäre es großartig, hier das Beispiel von Kornel Kisielewicz zu vervollständigen, weil ich nirgendwo sonst ein gutes Beispiel dafür sehe. –

3

Sie haben bereits einige gute Antworten erhalten, aber es scheint, dass es sich lohnt hinzuzufügen, dass C++ 0x eine std::align() enthält, was die Implementierung solcher Dinge ein bisschen einfacher machen sollte.

+1

Gibt es ein Beispiel für die Verwendung als Zuweiser? –

0

Anstatt Ihren eigenen Zuweiser zu schreiben, wie suggested before, können Sie verwenden.