SSE4 ha PMAXSD
o PMAXUD
per numeri interi a 32 bit con segno/senza segno, che potrebbero essere utili.
SSE2 ha MAXPD
e MAXSD
che confrontano tra e attraverso coppie di doppio, in modo da seguire la N/2-1 MAXPDs con uno MAXSD per ottenere il massimo di un vettore di n, con il solito intreccio dei carichi e delle operazioni.
Ci sono MIN equivalenti di quanto sopra.
per il doppio caso, probabilmente non state andando a fare meglio in assembler di un ++ compiler semidecente C in modalità 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
dove min_max calcola min e max di un array di 500 camere doppie 100.000 volte utilizzando un ciclo 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;
}
In risposta alla seconda parte, l'ottimizzazione tradizionale per rimuovere ramificazione da un'operazione di massima è quello di confrontare i valori, ottenere la bandiera come cantare le bit (dando 0 o 1), sottrarre uno (dando 0 o 0xffff_ffff) e 'e' esso con lo xor dei due risultati possibili, in modo da ottenere l'equivalente di (a > best ? (current_index^best_index) : 0)^best_index)
. Dubito che ci sia un semplice modo per farlo, semplicemente perché l'SSE tende a operare su valori compressi piuttosto che su valori taggati; ci sono alcune operazioni sull'indice orizzontale, quindi puoi provare a trovare il massimo, quindi sottrarre quello da tutti gli elementi nel vettore originale, quindi raccogliere il bit del segno, e lo zero firmato corrisponde all'indice del massimo, ma probabilmente non essere un miglioramento a meno che non stiate usando shorts o byte.
Qual è la lingua host? Se è c/C++ non mi preoccuperei troppo. –
massimo di circa 300 doppi è nel ciclo più interno del programma di grandi dimensioni. L'85% del tempo è trascorso in circa 10 delle 8.000 linee di codice. Il linguaggio host non ha importanza solo per questo. Ma sì, è C++ –