2010-12-07 14 views
5

Pregunta básica: Tengo una caja dimensional k. Tengo un vector de límites superiores y límites inferiores. ¿Cuál es la forma más eficiente de enumerar las coordenadas de los vértices?¿Cuál es la manera más eficiente de enumerar vértices de hipercubo k dimensional en C++?

Antecedentes: Como ejemplo, supongo que tengo una caja tridimensional. ¿Cuál es el algoritmo/código más eficiente para obtener:

vertex[0] = (0, 0, 0) -> (L_0, L_1, L_2) 
vertex[1] = (0, 0, 1) -> (L_0, L_1, U_2) 
vertex[2] = (0, 1, 0) -> (L_0, U_1, L_2) 
vertex[3] = (0, 1, 1) -> (L_0, U_1, U_2) 

vertex[4] = (1, 0, 0) -> (U_0, L_1, L_2) 
vertex[5] = (1, 0, 1) -> (U_0, L_1, U_2) 
vertex[6] = (1, 1, 0) -> (U_0, U_1, L_2) 
vertex[7] = (1, 1, 1) -> (U_0, U_1, U_2) 

donde L_0 corresponde al elemento de orden 0 de la vector límite inferior & igualmente U_2 es ​​el segundo elemento del vector límite superior.

Mi Código:

const unsigned int nVertices = ((unsigned int)(floor(std::pow(2.0, double(nDimensions))))); 

for (unsigned int idx=0; idx < nVertices; ++idx) 
{ 
    for (unsigned int k=0; k < nDimensions; ++k) 
    { 
     if (0x00000001 & (idx >> k)) 
     { 
     bound[idx][k] = upperBound[k]; 
     } 
     else 
     { 
     bound[idx][k] = lowerBound[k]; 
     } 
    } 
} 

donde la variable bound se declara como:

std::vector< std::vector<double> > bound(nVertices); 

pero tengo pre-tamaño que a fin de no perder el tiempo en la memoria de asignación de bucle . Necesito llamar al procedimiento anterior unas 50,000,000 de veces cada vez que ejecuto mi algoritmo, así que necesito que esto sea realmente eficiente.

Posibles Subpreguntas: ¿Tiende a ser más rápido cambiar por k en lugar de cambiar siempre por 1 y almacenar un resultado intermedio? (¿Debo estar utilizando >> = ??)

+0

¿Qué tan opuesto sería usted a hurgar en el ensamblador? Y, una cosa más: perfil, perfil, perfil. Toma las sugerencias aquí y prueba luego para ver dónde están rápido y dónde están lentas. –

+0

¿Qué tan grande es k? ¿Esta arreglado? –

+0

He perfilado el código usando Vtune con MSVS 2005. Estoy contento de trabajar en ensamblador, aunque recopilo una variedad de objetivos, por lo que soy más particular con las sugerencias algorítmicas que con la arquitectura específica, pero si realmente canta, todo ¡el mejor! - Debo señalar: los objetivos Xeon X5550 y Core i7 930 principalmente. –

Respuesta

4

es probable que vaya más rápido si se puede reducir la bifurcación condicional:

bound[idx][k] = upperLowerBounds[(idx >> k) & 1][k]; 

Es posible mejorar las cosas aún más si se puede intercalar los límites superior e inferior en una sola matriz:

bound[idx][k] = upperLowerBounds[(k << 1) | (idx >> k)&1]; 

no sé si el cambio incremental idx ayuda. Es lo suficientemente simple de implementar, por lo que vale la pena intentarlo.

+0

Mi primer paso en la implementación de su sugerencia me dio una mejora del 40%. Gracias! –

Cuestiones relacionadas