SSE4 tiene PMAXSD
o para enteros de 32 bits con signo/sin signo, que pueden ser útiles.
SSE2 tiene MAXPD
y MAXSD
que comparan entre ya través de pares de dobles, por lo que sigue n/2-1 MAXPDs con una MAXSD para obtener el máximo de un vector de n, con el entrelazado habitual de cargas y operaciones.
Hay MIN equivalentes de los anteriores.
Para el doble caso, es probable que no va a hacer mejor en ensamblador que un compilador de C de media decente ++ en modo SSE:
peregrino:$ g++ -O3 src/min_max.cpp -o bin/min_max
peregrino:$ g++ -O3 -msse4 -mfpmath=sse src/min_max.cpp -o bin/min_max_sse
peregrino:$ time bin/min_max
0,40
real 0m0.874s
user 0m0.796s
sys 0m0.004s
peregrino:$ time bin/min_max_sse
0,40
real 0m0.457s
user 0m0.404s
sys 0m0.000s
donde min_max calcula mínimo y máximo de una matriz de 500 dobles 100.000 veces usando un bucle ingenua:
bool min_max (double array[], size_t len, double& min, double& max)
{
double min_value = array [ 0 ];
double max_value = array [ 0 ];
for (size_t index = 1; index < len; ++index) {
if (array [ index ] < min_value) min_value = array [ index ];
if (array [ index ] > max_value) max_value = array [ index ];
}
min = min_value;
max = max_value;
}
En respuesta a la segunda parte, la optimización tradicional para eliminar la ramificación de una operación máx es comparar los valores, conseguir la bandera como un cantar le bit (dando 0 o 1), resta uno (dando 0 o 0xffff_ffff) y 'y' con el xor de los dos resultados posibles, por lo que obtienes el equivalente de (a > best ? (current_index^best_index) : 0)^best_index)
. Dudo que haya una forma sencilla de SSE de hacerlo, simplemente porque SSE tiende a operar en valores empaquetados en lugar de valores etiquetados; hay algunas operaciones de índice horizontal, por lo que podría intentar encontrar el máximo, luego restarlo de todos los elementos en el vector original, luego juntar el bit de signo, y el cero con signo correspondería al índice del máximo, pero eso probablemente no ser una mejora a menos que estuvieras usando cortos o bytes.
¿Cuál es el idioma de acogida? Si es c/C++, no me preocuparía demasiado. –
máximo de alrededor de 300 dobles está en el bucle más interno del programa grande. 85% del tiempo se gasta en aproximadamente 10 de las 8'000 líneas de código. El lenguaje de host no importa solo por eso. Pero sí, es C++ –