visual vectores una suma studio puede net multiplicacion matriz matrices hace dinamico como asignar arreglos arreglo array 3x3 c++ c arrays copy

c++ - una - suma de vectores visual basic



¿Una manera eficiente de convertir una matriz corta de 16 bits en una matriz int de 32 bits? (7)

  1. Inicialice un int[] con la misma longitud que el short[] .
  2. Iterar sobre el short[] , asignando el elemento i th del short[] a la i th posición del int[] .

¿Cuál es la forma más eficiente de convertir una matriz de números cortos sin firmar (16 bits por valor) en una matriz de números de entradas sin firmar (32 bits por valor)?


Aquí un bucle desenrollado accediendo en trozos de 64 bits. Puede ser un poco más rápido que el simple bucle, pero las pruebas son la única forma de saberlo.

Suponiendo que N es un múltiplo de cuatro, ese tamaño de (corto) es de 16 bits y el trabajo con registros de 64 bits funciona.

typedef union u { uint16_t us[4]; uint32_t ui[2]; uint64_t ull; } u_t; ushort_t src[N] = ...; uint_t dst[N]; u_t *p_src = (u_t *) src; u_t *p_dst = (u_t *) dst; uint_t i; u_t tmp, tmp2; for(i=0; i<N/4; i++) { tmp = p_src[i]; /* Read four shorts in one read access */ tmp2.ui[0] = tmp.us[0]; /* The union trick avoids complicated shifts that are furthermore dependent on endianness. */ tmp2.ui[1] = tmp.us[1]; /* The compiler should take care of optimal assembly decomposition. */ p_dst[2*i] = tmp2; /* Write the two first ints in one write access. */ tmp2.ui[0] = tmp.us[2]; tmp2.ui[1] = tmp.us[3]; p_dst[2*i+1] = tmp2; /* Write the 2 next ints in 1 write access. */ }

EDITAR

Así que lo probé en SUN M5000 (SPARC64 VII 2.5 GHz) con GCC 3.4.1 en modo de 64 bits en una matriz de 4,000,000 elementos. La implementación ingenua es un poco más rápida. Lo intenté con SUNStudio 12 y con GCC 4.3, pero ni siquiera he podido compilar el programa debido al tamaño de la matriz.

EDIT2

Logré compilarlo ahora en GCC 4.3. La versión optimizada es un poco más rápida que la ingenua.

GCC 3.4 GCC 4.3 naive 11.1 ms 11.8 ms optimized 12.4 ms 10.0 ms

EDITAR3

Podemos concluir que, en lo que respecta a C, no se moleste con una versión optimizada del bucle de copia, la ganancia es tan baja que el riesgo de error supera el beneficio.


Cópialo.

unsigned short source[]; // … unsigned int target[]; // … unsigned short* const end = source + sizeof source / sizeof source[0]; std::copy(source, end, target);

std::copy internamente el mejor mecanismo de copia para los tipos de entrada dados. En este caso, sin embargo, probablemente no haya mejor manera que copiar los elementos individualmente en un bucle.


En muchas arquitecturas, una reducción de do-while puede ser más rápida que los bucles for y while propuestos aquí. Algo como:

unsigned short ushorts[M]; unsigned int uints[N]; int i = M-1; do{ uints[i] = ushorts[i]; i--; } while(i >= 0);

El compilador puede ocuparse de la mayoría de las optimizaciones, como el desenrollado de bucles, pero en general lo anterior es más rápido (en muchas arquitecturas) porque:

  • Obtiene la primera iteración de forma gratuita en un do-while inactividad en comparación con un while o for
  • El bucle termina cuando i = 0. La comprobación de 0 puede guardar una instrucción porque el indicador de cero se establece automáticamente. Si el bucle se incrementó y terminó cuando i = M, entonces puede necesitar una instrucción de comparación adicional para probar si i <M.

También puede haber formas más rápidas, como hacerlo completamente con aritmética de punteros. Esto podría convertirse en un divertido ejercicio de desensamblar el código y analizarlo para ver qué aparece más rápido. Todo depende de la arquitectura. Afortunadamente, otros han hecho este trabajo por ti con std :: copy.


Qué pasa

unsigned short src[N] = ...; unsigned int dst[N]; for(i=0; i<N; ++i) dst[i] = src[i];

Para una versión en C ++, las respuestas de Konrad o Nawaz son seguramente las más adecuadas.


Simplemente copie la dirección de la matriz corta para acceder a cada elemento de la matriz corta, como pTp32[0...LEN-1].arr[0..1] :

unsigned short shrtArray[LEN]; //.. union type32 { short arr[2]; int value; }; type32 * pTp32 = (type32*)shrtArray;


Use std::copy en C ++:

#include<algorithm> //must include unsigned short ushorts[M]; //where M is some const +ve integer unsigned int uints[N]; //where N >= M //...fill ushorts std::copy(ushorts, ushorts+M, uints);

Y en C, use el bucle manual (de hecho, puede usar el bucle manual tanto en C como en C ++):

int i = 0; while( i < M ) { uints[i] = ushorts[i]; ++i; }