2012-11-16 12 views
6

Angenommen, ich habe einen 2-Element-Vektor wie folgt definiert (die GCC-Syntax für verpackte Vektoren)Computing x^y mit GCC Vektor intrinsics

// packed vector of 2-elements 
typedef double v2d __attribute__((vector_size(sizeof(double)*2))); 

v2d x = ...; 
double y = ...; 

x[0] = pow(x[0], y) 
x[1] = pow(x[1], y) 

Ich mag gerne wissen, ob es ein schnellerer Weg zu tun sind die zwei Leistungsberechnungen unter Verwendung von Vektoroperationen. Die Architektur ist GCC auf x86-64 und plattformspezifischer Code ist in Ordnung.

+0

eine generische Potenzfunktion Implementierung ist schwierig, da es da Sie ist sowohl benötigen 'exp()' und 'log()'. Es kann wahrscheinlich zu viel Verzweigung geben, um eine lohnende Beschleunigung durch Vektorisierung zu erhalten. Aber ich spekuliere nur. – Mysticial

+0

Nein, der SIMD-Befehlssatz hat keine Operationen, die eine Beschleunigung von pow() ermöglichen. SSE2 hat nur add, sub, mul, div, max, min und sqrt. Es gibt nicht einmal eine nicht vektorisierte Anweisung dafür. –

+2

Es kann etwas Hoffnung geben, wenn "y" auf unsigned Int statt Double beschränkt ist. Tatsächlich konnten mit dem klassischen "Shift-and-Multiply" -Algorithmus die beiden Vektorelemente parallel ausgewertet werden. Nur meine Vermutung. –

Antwort

5

Ja, dies sollte möglich sein, wenn Sie keine speziellen Fälle haben (negative Zahlen, 0, 1, NaN etc ...), so dass der Codepfad linear ist.

Here ist der generische Code für die pow Funktion für IEEE754 verdoppelt, hat es keine Schleifen Konstrukte, also wenn Sie alle Sonderfälle ausarbeiten, scheint die Vektorisierung einfach. Habe Spaß.

+2

Haha ... Ich verstehe, was du mit "viel Spaß" meinst. :) – Mysticial

1

Sie können Schleife über die Elemente direkt und mit der richtigen Optionen GCC und ICC verwenden, um eine vektorisiert pow Funktion

#include <math.h> 
typedef double vnd __attribute__((vector_size(sizeof(double)*2))); 

vnd foo(vnd x, vnd y) { 
    #pragma omp simd 
    for(int i=0; i<2; i++) x[i] = pow(x[i], y[i]); 
    return x; 
} 

Mit nur -O2 ICC erzeugt einfach call __svml_pow2. SVML (Short Vector Math Library) ist Intels vektorisierte Mathematik-Bibliothek. With -Ofast -fopenmp GCC generiert einfach call _ZGVbN2vv___pow_finite.

Clang vektorisiert es nicht.

https://godbolt.org/g/pjpzFX