Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

2009-01-29

Another MMX/SSE/SSE2 optimization bugs

All SSE2 platform

All SSE2 platform except to Windows

  • 475225 - Add JPEG optimization for x86_64 platform
    Windows x86でしかSSE2使ってないので、GCC系のプラットフォームにも移植する予定。といっても、Fedoraとかだと、--with-system-jpegつけてビルドするからオフィシャルビルドとかしか影響しないけど。

For Windows x64 only (will be only on mozilla-central)

2009-01-28

ふと思ったmozillaのSSE2最適化

/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
695 void
696 row_callback(png_structp png_ptr, png_bytep new_row,
697              png_uint_32 row_num, int pass)
698 {
 :
 :
793     case gfxIFormats::RGB_A1:
794       {
795         for (PRUint32 x=iwidth; x>0; --x) {
796           *cptr32++ = GFX_PACKED_PIXEL(line[3]?0xFF:0x00, line[0], line[1], line[2]);
797           if (line[3] == 0)
798             rowHasNoAlpha = PR_FALSE;
799           line += 4;
800         }
801       }
802       break;
803     case gfxIFormats::RGB_A8:
804       {
805         for (PRUint32 x=width; x>0; --x) {
806           *cptr32++ = GFX_PACKED_PIXEL(line[3], line[0], line[1], line[2]);
807           if (line[3] != 0xff)
808             rowHasNoAlpha = PR_FALSE;
809           line += 4;
810         }
811       }

ここで使ってる GFX_PACKED_PIXEL のマクロってどうなっているかと思ったら、

/gfx/thebes/public/gfxColor.h
118 /**
119  * Fast approximate division by 255. It has the property that
120  * for all 0 <= n <= 255*255, FAST_DIVIDE_BY_255(n) == n/255.
121  * But it only uses two adds and two shifts instead of an 
122  * integer division (which is expensive on many processors).
123  *
124  * equivalent to ((v)/255)
125  */
126 #define GFX_DIVIDE_BY_255(v)  \
127      (((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16)
128 
129 /**
130  * Fast premultiply macro
131  *
132  * equivalent to (((c)*(a))/255)
133  */
134 #define GFX_PREMULTIPLY(c,a) GFX_DIVIDE_BY_255((c)*(a))
135 
136 /** 
137  * Macro to pack the 4 8-bit channels (A,R,G,B) 
138  * into a 32-bit packed premultiplied pixel.
139  *
140  * The checks for 0 alpha or max alpha ensure that the
141  * compiler selects the quicked calculation when alpha is constant.
142  */
143 #define GFX_PACKED_PIXEL(a,r,g,b)                                       \
144     ((a) == 0x00) ? 0x00000000 :                                        \
145     ((a) == 0xFF) ? ((0xFF << 24) | ((r) << 16) | ((g) << 8) | (b))     \
146                   : ((a) << 24) |                                       \
147                     (GFX_PREMULTIPLY(r,a) << 16) |                      \
148                     (GFX_PREMULTIPLY(g,a) << 8) |                       \
149                     (GFX_PREMULTIPLY(b,a))

だから、アルファブレンディングしたPNGを持ってくると遅すぎじゃないかな?

こんな感じのパックドコードをSSE2で実装すれば約2倍くらいは速くなるような。

xmm0080 = _mm_set1_epi16(0x0080);
xmm0101 = _mm_set1_epi16(0x0101);
xmmAlpha = _mm_set_epi32(0x00ff0000, 0x00000000, 0x00ff0000, 0x00000000);

data = _mm_loadu_si128((__m128i*)src);
dataLo = _mm_unpacklo_epi8 (data, _mm_setzero_si128 ());
dataHi = _mm_unpackhi_epi8 (data, _mm_setzero_si128 ());

alphaLo = _mm_shufflelo_epi16 (dataLo, _MM_SHUFFLE(3, 3, 3, 3));
alphaHi = _mm_shufflelo_epi16 (dataHi, _MM_SHUFFLE(3, 3, 3, 3));
alphaLo = _mm_shufflehi_epi16 (alphaLo, _MM_SHUFFLE(3, 3, 3, 3));
alphaHi = _mm_shufflehi_epi16 (alphaHi, _MM_SHUFFLE(3, 3, 3, 3));

alphaLo = _mm_or_si128(alphaLo, xmmAlpha);
alphaHi = _mm_or_si128(alphaHi, xmmAlpha);

dataLo = _mm_shufflelo_epi16 (dataLo, _MM_SHUFFLE(3, 0, 1, 2));
dataLo = _mm_shufflehi_epi16 (dataLo, _MM_SHUFFLE(3, 0, 1, 2));
dataHi = _mm_shufflelo_epi16 (dataHi, _MM_SHUFFLE(3, 0, 1, 2));
dataHi = _mm_shufflehi_epi16 (dataHi, _MM_SHUFFLE(3, 0, 1, 2));

dataLo = _mm_mullo_epi16(dataLo, alphaLo);
dataHi = _mm_mullo_epi16(dataHi, alphaHi);

dataLo = _mm_adds_epu16(dataLo, xmm0080);
dataHi = _mm_adds_epu16(dataHi, xmm0080);

dataLo = _mm_mulhi_epu16(dataLo, xmm0101);
dataHi = _mm_mulhi_epu16(dataHi, xmm0101);

data = _mm_packus_epi16 (dataLo, dataHi);
_mm_storeu_si128((__m128i*)dst, data);

今度テストしてみよう。

2009-01-21

Intel's AES-NI instructionsの各ソフトウェア上での実装

Westmere以降のIntelのCPUでは、新機能として、XMMレジスタを使ったAES暗号のための補助インストラクションが追加されているんだけど、チップに機能があったって、コードがなければ意味がない。

その実装の各ソフトウェアでの実装状況について。

Linux Kernel

http://lwn.net/Articles/311094/にパッチの投稿がある。まだ入ってないけど、パッチあり。

Network Security Services (NSS)

https://bugzilla.mozilla.org/show_bug.cgi?id=459248がバグエントリ。コードは既にコミットされていて、NSS 3.12.3 Beta1 から含まれる。でもLinux x86_64とSolarisのみ。

OpenSSL

http://groups.google.com/group/mailing.openssl.dev/browse_thread/thread/15d5fd5b74d528aeにパッチの投稿がある。まだ入ってないけど、パッチあり。

各暗号系の実装はCPUがリリースされた時点でそろってるっぽいよね。

2009-01-18

Windows 7を入れてみた

開発用に使っているノートPC (Dell XPS M1210) に、最近公開されているWindows 7のパブリックベータを入れてみた。

壊してもいい環境だったんで、アップグレードインストールした雑感。

  • アップグレードに4.5時間ほどかかった
  • 英語キーボードの環境だったのに、日本語キーボードに変えられた
  • Intel GM945のドライバがWindows Updateから入れられない

思ったよりは、いい感じかも。

2008-12-30

Firefoxに欠けているもの

Firefoxのシェアは20%を超えるくらいまで伸びているようだけど、これは今後ジリ貧になる可能性が高いと感じている。今のユーザー層というのは、一般のConsumerであって、企業ユーザーではない。

もし自分がSIerだったら、Firefoxを元にしたシステムの導入を選べない。ちょっと理由を書いていく。

LTS (Long Time Support)の欠如

まず、Firefoxのリリースとサポート終了日を確認してみる

リリースEnd Of Life
Firefox 1.02004年11月2006年4月
Firefox 1.52005年11月2007年5月
Firefox 2.02006年10月2008年12月
Firefox 3.02008年6月

次の表は企業用でもっともシェアのあるやつ。ちなみに触れておくと、メインストリーム終了ってのはプレミアサポート経由での個別バグフィックスサービス(基本的に無償)の提供が終了する日で、End Of Lifeはセキュリティ修正のホットフィックスも終了する日。金さえ払って契約しておけば、この期間が過ぎてても個別対応はあるそうだけど。。。(実際、サポート期間が切れる前に契約を事前にしておく必要があるらしい)

リリースメインストリーム終了End Of Life
Internet Explorer 6 with 20002001年9月2005年6月2010年7月
Internet Explorer 6 with XP2001年9月2009年4月2014年4月
Internet Explorer 7 with XP2006年11月未定(おそらくXPと同様)未定(おそらくXPと同様)
Internet Explorer 7 with Vista2007年1月未定(おそらくVistaと同様)未定(おそらくVistaと同様)

こう見るとわかるけど、MicrosoftとMozillaだとサポート期間が明らかに違う。Web DesignerやConsumerだと、なぜ早く終わらないの?。検証しないといけない環境が多すぎるという声は当然あると思うけど、企業からの声は逆で、もうやめちゃうの?早すぎ。延長してくれというクレームが多い。

いくら標準をうたっているブラウザであってもトリッキーなページの解釈についてはバグがつきもの(バグをつくようなAcid Testを見ればわかる)。そのため、システム提案・開発・導入時にはバージョンも指定して、そのバージョンで固定する場合が当然かと思う。そのとき、FirefoxのようなすぐEnd Of Lifeを迎え、なおかつ、新しいバージョンとのオーバーラップ期間もほとんどないものを選ぶなんて、基本的には自殺行為もいいところ。

企業でひとつのシステムが稼働するのは、3年から5年以上。そのため、それを計算して導入を検討するんだけど、Firefoxのようなサポート期間が短いものだと、検討の対象にできない。

Linuxだとディストリビューターが管理も行うから、ちゃんとブラウザのバージョンが固定かと思ったら、タチが悪い。Red Hat Enterprise Linux 5には、Firefox 1.5が付いているんだけど、5.2にあげるとFirefox 3.0になってしまうという。これを聞いて、RHELをデスクトップには推奨できなくなった。(SuSEはどうか知らない)

Deployment

IT企業のようにPCだけ渡されて、「好きにしていいよ、Proxyはこれ。またメールについては、SMTPはこれ、POP3はこれ、IMAPだとこれね」って教えられるようなところだと別にどうでもいいかもしれないけど、通常の企業の場合、そんな設定さえも自動にできないとIT部門のコストがかかってしょうがない。

Firefoxでも、プロキシ構成についてはスクリプト(通称PACファイル)を仕込んでおけばプロキシサーバーの変更を一手に行える。

これがInternet Explorerだと、その機能に加えて Active Directoryのグループポリシー機能を利用した設定の自動変更さえも一手に行える。システム管理側としては(動くか動かないかは抜きにして)選ぶ理由にもなり得る。

また、セキュリティアップデートというのがくせ者。アップデートを簡単に管理者がコントロールできるようにする機能もないので、それが帯域を占有したり、勝手にアップデートをされた結果、イントラネット上のツールが動作しなくなるということも発生しうる。そのために(ツールの修正を行うまで、ダウングレードを手動で行わせたりするような)追加コストでさえも無駄に発生してしまう。Microsoftだとすべては無償のツール使ってできるんだよね。

じゃ、それで?

明らかに足りない部分はあるので、こういうメンテナンスビリティを来年をちょっとやっていこうかなぁとは思っているんだが。今考えてるのはそんなところ。