2012-11-16 21 views
6

は、私は次のように2要素ベクトルは(パックされたベクトルのGCCの構文を使用して)定義があるとしコンピューティングのx^yの

// 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) 

私が行うにはより高速な方法がありますかどうかを知りたいのですがベクトル演算を用いた2つのパワー計算。アーキテクチャはx86-64上のGCCであり、プラットフォーム固有のコードはOKです。

+0

は困難です。ベクトル化によって価値のあるスピードアップを得るには、分岐が多すぎる可能性があります。しかし、私は思っているだけです。 – Mysticial

+0

いいえ、SIMD命令セットにはpow()の高速化を可能にする操作はありません。 SSE2には、add、sub、mul、div、max、min、およびsqrtしかありません。それにはベクトル化されていない命令さえありません。 –

+2

"y"がdoubleではなくunsigned intに制限されていれば、ある程度の希望があるかもしれません。実際、古典的な「シフト・アンド・マルチプライ」アルゴリズムでは、2つのベクトルの要素を並行して評価することができます。ちょうど私の推測。 –

答えて

5

はい、コードパスが線形になるように特殊なケース(負の数、0,1、NaNなど)がない場合は可能です。

Hereは、IEEE754倍音用の汎用コードであり、ループ構成はありません。したがって、すべての特殊なケースを除外すると、ベクトル化は簡単です。楽しむ。

+2

ハッハッハ...「楽しんで」という言いたいことが分かります。 :) – Mysticial

1

あなたは要素をループが直接、ちょうど-O2 ICCは、単にcall __svml_pow2を生成すると、右のオプションGCCおよびICCは、ベクトル化pow機能

#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; 
} 

を使用するとことができます。 SVML(ショートベクトル数学ライブラリ)は、インテルのベクトル化された数学ライブラリです。 With -Ofast -fopenmp GCCは単にcall _ZGVbN2vv___pow_finiteを生成します。

Clangはベクトル化しません。それはあなたが両方 `EXP()`と `ログを()`必要があるためであるとして、一般的な電源機能を実装

https://godbolt.org/g/pjpzFX

関連する問題