2010-01-08 20 views
12

¿Hay alguna forma de imponer la alineación del contenedor STL al byte específico, utilizando el atributo (alineado) tal vez? los compiladores de destino no son Microsoft Visual C++.Alineación de estructura de datos C++ STL, vectorización de algoritmo

Qué bibliotecas, si las hay, proporcionan plantillas especializadas de algoritmos STL que tienen una vectorización explícita específica, p. SSE. Mis compiladores de interés son g ++, Intel e IBM XL.

Respuesta

12

Con contenedores STL, puede proporcionar su propio asignador a través de un parámetro de plantilla opcional. No recomendaría escribir un asignador completo desde cero, pero podría escribir uno que sea solo un contenedor alrededor de new y delete, pero asegura que la memoria devuelta cumpla con los requisitos de alineación. (Por ejemplo, si necesita n bytes con la alineación de 16 bytes, se utiliza new asignar n + 15 bytes y devuelve un puntero a la primera dirección alineadas de 16 bytes en ese bloque.)

Pero podría ser suficiente sólo para añadir el atributo de alineación al tipo de elemento. Eso está fuera del alcance del estándar, por lo que tendrá que verificar la documentación del compilador y probarlo.

2

Necesita un asignador personalizado que devuelva el almacenamiento alineado. Eso debería resolver tu problema.

7

Necesita un asignador personalizado aprobado. Se puede construir una sobre la std::allocator con bastante facilidad:

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(); 
    } 
}; 

Lo único que falta aquí es el aligned_malloc, aligned_realloc y aligned_free. O necesita implementarlos usted mismo (no debería ser tan difícil) o buscar versiones de ellos en Internet (he visto al menos uno en el motor OGRE).

+1

@Anycorn, ¿alguna vez implementó esto? Parece que sería genial completar el ejemplo de Kornel Kisielewicz porque realmente no veo un buen ejemplo de esto en ningún otro lado en línea. –

3

Ya has obtenido algunas buenas respuestas, pero parece que vale la pena agregar que C++ 0x incluye un std::align(), lo que debería facilitar la implementación de este tipo de cosas.

+1

¿Hay algún ejemplo de usar esto como asignador en alguna parte? –

Cuestiones relacionadas