もきもき3D

アクセスカウンタ

zoom RSS SSEでのFloat→Doubleキャスト

<<   作成日時 : 2011/02/11 21:19   >>

ブログ気持玉 0 / トラックバック 0 / コメント 0

 値個別の場合は選択肢は無いから捨て置く。
 __m128(float[4])をDouble[4]にして処理する事を考える。


 以下のソース内のDoubleの加算は整数向けの処理(Shuffle_epi)をした後に浮動小数処理をした場合にどうなるかを見る為。
 f2は、そのままではmovhlpsに先立ってxmmレジスタの初期化を要求されるけど、勝手にxorpdが挿入される。

 呼び出し元とは別ファイル(別obj)。
 10万x100回を1セットとしてf1→f2→f3→f1→f2→f3の様に続けて実行。
 rdtsc()カウンタの平均(一回当たり)で、f1=20、f2=20、f3=21、f4=22になった。

 f1のShuffle_epiがFlt→Dblに先立つ限りは整数→浮動小数のペナルティ対象にならないのか、f2のmovhlpsがそれを覆す程に遅いのかは不明。
 でもf2はxorpdを挿入されてる事を考えると実際は有利なのかも知れない。 実用時に使用済みのxmmレジスタがあればxorpdは挿入されなくて済む場合があるゆえ。

 f3はasm時の行数が一番少なかったけど駄目っすね('з`)
 でもまぁ速度差を考えるとソースが見易く、省サイズってのは利点かも知れない。

ここまではdouble[4]の場合。

 求める結果をdouble[3]とすると([2]のadd/storeをsdに、f4の[3]を無しに)、f1=19、f2=19、f3=20、f4=18になった。
 この場合もcvtps2pdのままであえてcvtss2sdにしない。
 ss2sdにすると、f4以外は皆してxorpdを挿入され、スコアはボロボロになる(w +1〜2程度だけど1割だかんね。
 ちなみに、f4、イントリシックではないd=v+(double)fではxorpdが挿入されない(・з・)

 下位しか使わない命令に先立ってxorpdを突っ込むのがgcc/MinGWのおせっかいなのか、VCやIntelでも起こるイントリンシック使用時の推奨されたコンパイル規定なのかは不明(・з・)

追記:
 shuffle_ps(,,0xEE)もあったけど、epiやmovhlと差無し。 xorpd挿入もされる。
 速度傾向(バラツキ)的にはshuffle_epiに近そう。 xorpdを排除出来る(又は関数内の隔絶した所で処理出来る)なら(遅)shf_epi>shf_ps>movhl_ps(速)となるかも。

 まぁ骨董のAthlon64(venice)での話しだから、C2Dやi7じゃ通じないだろうけで('з`)

void f1(float *fv, double *dv)
{
__m128 xm0f = _mm_load_ps(fv); // 3:2:1:0
__m128 xm1f = (__m128)_mm_shuffle_epi32((__m128i)xm0f, 0xEE);// 1110 1110 bit:0xEE
__m128d xm0a = _mm_cvtps_pd(xm0f); // -:-:1:0
__m128d xm0b = _mm_cvtps_pd(xm1f); // -:-:3:2
__m128d xm={.1,.2};
xm0a = _mm_add_pd(xm0a, xm);
xm0b = _mm_add_pd(xm0b, xm);
_mm_store_pd(&dv[0], xm0a); // 1:0
_mm_store_pd(&dv[2], xm0b); // -:2
}
void f2(float *fv, double *dv)
{
__m128 xm0f = _mm_load_ps(fv); // 3:2:1:0
__m128 xm1f = _mm_movehl_ps(xm1f, xm0f); // 3:2:3:2
__m128d xm0a = _mm_cvtps_pd(xm0f); // -:-:1:0
__m128d xm0b = _mm_cvtps_pd(xm1f); // -:-:3:2
__m128d xm={.1,.2};
xm0a = _mm_add_pd(xm0a, xm);
xm0b = _mm_add_pd(xm0b, xm);
_mm_store_pd(&dv[0], xm0a); // 1:0
_mm_store_pd(&dv[2], xm0b); // -:2
}
void f3(float *fv, double *dv)
{
__m128d xm0a = _mm_cvtps_pd(*(__m128*)&fv[0]); // -:-:1:0
__m128d xm0b = _mm_cvtps_pd(*(__m128*)&fv[2]); // -:-:3:2
__m128d xm={.1,.2};
xm0a = _mm_add_pd(xm0a, xm);
xm0b = _mm_add_pd(xm0b, xm);
_mm_store_pd(&dv[0], xm0a); // 1:0
_mm_store_pd(&dv[2], xm0b); // -:2
}
void f4(float *fv, double *dv)
{
dv[0] = 0.1 + (double)fv[0];
dv[1] = 0.2 + (double)fv[1];
dv[2] = 0.1 + (double)fv[2];
dv[3] = 0.2 + (double)fv[3];
}

テーマ

注目テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
SSEでのFloat→Doubleキャスト もきもき3D/BIGLOBEウェブリブログ
文字サイズ:       閉じる