2013/07/27

png のファイルサイズを最適化するコマンド

png ファイルって、便利ですけど可逆のはずなのに、なぜか出力するソフトによってファイルサイズが違ったりしますよね。

更に、前回のエントリと同様に、PageSpeed Insights にかけてみると、こんなことを言われるわけです。
以下の画像を最適化すると、サイズを 15.7 KB(7%)削減できます。
    http://example.com/.../image_thumb.png を可逆圧縮すると 8.5 KB(7%)削減できます。
そこで、コマンド一発通したら png ファイルを小さくしてくれるコマンドがあったら便利ですよね。探して見ました。
  • optipng - 進化した PNG (Portable Network Graphics) オプティマイザ
  • pngnq - PNG (Portable Network Graphics) 画像最適化ツール
  • pngcrush - PNG (Portable Network Graphics) ファイルを最適化
aptitude search したらこれぐらい見つかりました。

ひとつ注意として、pngnq だけ他とちょっと違います。pngnq は、32-bit RGBA な PNG ファイルを 8bit RGBA に変換するファイルです。つまり、強制的に小さくなりますし、(通常は)非可逆です。GIF みたいなものです。

それぞれ使ってみます。変換するファイルは、256x256 の GIMP で生成したファイルです。(ODCP のロゴ)
  • Original
    • 37652 byte
  • `convert in.png out.png` (参考)
    • 38654 byte
  • `optipng in.png` => in.png
    • 24482 byte
  • `pngcrush in.png out.png`
    • 24482 byte
  • `pngnq in.png` => out-nq8.png
    • 13853 byte
参考で ImageMagick で convert した結果も乗せて見ました。サイズ増えてますwww

pngnq は 8bit に変換するだけあって、さすがに減ってます。グラデーションとかな png だとがっつり劣化するので、用途によりますかね。

optipng と pngcrush は同じ結果でした。好きな方を使えばいいと思います。

Debian の Apache では Javascript の gzip 圧縮は有効になってない?

Google の PageSpeed Insights って知ってますか?
  • https://developers.google.com/speed/pagespeed/insights
Web ページの表示速度を最適化させるために、あらゆるやるべきことを教えてくれます。簡単にでることもあれば、こんなの無理だろという指摘まで...

最近は、このあたりを最適化してるかしてないかで Google の表示順位も変わってくるらしいので、暇なときに簡単にできそうな問題は修正しておくと良いです。

ところで、僕のある Dokuwiki のサイトを PageSpeed Insights にかけてみたらこんな結果が出てきました。
以下のリソースを gzip で圧縮すると転送サイズを 294.4 KB(71%)削減できます。
    http://example.com/lib/exe/js.php?tseed=1373562644 を圧縮すると 294.4 KB(71%)削減できます。
ん?という感じです。Apache の gzip 圧縮は mod_deflate で有効になっているはずなのですが、確かに HTTP ヘッダを観測してみると、gzip でも deflate でも圧縮されてません。

2013/07/22

glibc の関数の引数の数について調べてみた

Open Design Computer Project で作っている mist32 プロセッサの、関数呼び出し規則と割り込みについて考えてる間に、あるひとつの疑問が...

ふつうの関数は、どれぐらいの引数を使うのか

平均と言うよりは、最大でどれぐらいまでの引数が使われることが普通なのか。

何故こんなデータが欲しいかというと、関数呼び出し規則 (Calling conventions) でレジスタに引数を乗せることは確定だが、どの程度引数レジスタを用意すればいいのか、という事を決めたい。

関数呼び出し規則では、レジスタに呼び出し元か呼び出し先か、どちらで保存するかを定義しなければならない。基本的には、呼び出し先保存 (caller-saved) なレジスタの方が、効率が良いのである。実際に使われたレジスタしか退避することがないから。

全部引数に載せればいいじゃん?って思うかもしれないけど、レジスタが許す限り全部引数をレジスタに乗せることに決めた場合、すべてのレジスタが呼び出し元保存 (callee saved) なレジスタになるので、問題が起きる。呼び出した先の関数がどのレジスタを使ってるのかなどわからないので、呼び出し元の関数で使ってる変数レジスタをすべて退避する必要がある。その先の関数でそれを使っていないかもしれないのに。また、割り込みの際にも、呼び出し元保存のレジスタは、基本的に割り込みハンドラで保存しなければいけないし、多すぎるといいことはない。

つまり、どの程度の数の引数が一般的に使われるかがわかれば、ほとんどの数の引数をレジスタ渡しで実現しつつ、無駄なレジスタ退避を少なくすることができる、理想の引数レジスタの個数をなんとなく予測することができる。

2013/07/18

エンディアン変換とバイトアクセス

最近、Open Design Computer Project で mist32 プロセッサのシミュレーターを作っています。I/O のエミュレーションにもある程度対応してます。
https://github.com/techno/mist32-simulator

そこで気づいたことをひとつ書こうかなと。あたりまえのことなのですが。

ビッグエンディアンとリトルエンディアン

ご存知の通り、この世のコンピューターは内部的にエンディアンやバイトオーダーと言われるような、1ワードのバイト列をどのようにメモリ上に配置するか、という手法が大きく分けると2つあります。

Data: 0x1234ABCD

                0  1  2  3
Big Endian:    12 34 AB CD
Little Endian: CD AB 34 12

上記が、ビッグエンディアンとリトルエンディアンの概要です。ビッグエンディアンの方が人間には自然に見えますが、コンピューター的にはそうでない面もあり、一長一短です。一般的に使われている x86 はリトルエンディアンを使っています。

ファイルシステムや、ネットワークプロトコルなどによって、エンディアンは普通は規定されています。(FAT はリトルエンディアン、ネットワークはビッグエンディアン) しかしながら、ELF のようなメモリイメージのようなフォーマットは、そう簡単に行きません。

2013/07/16

Debian で起動時に NFS マウントが詰まる問題

某所で運用しているシステムで、Debian squeeze で HA 化されたストレージに対して、起動時に NFS マウントしています。

/etc/fstab の記述はこんなかんじです。
192.168.0.xxx:/nfs/var/www /var/www nfs rw,hard,intr,rsize=8192,wsize=8192 0 0

ところが、起動時に "Waiting for /var/www..." で詰まって、タイムアウトするまでブートシーケンスが止まる、しかも結局マウントされない、という問題が起きてました。しかしながら、起動した後 mount -a すると正常にマウントされます...

/var/www がマウントされないと、その後の apache の起動もコケるので、非常に良くない状況です。再起動するたびに、手動でマウントするようなことはしていられません...

原因を探ってみたところ、起動時に nfs のマウントを司っているのは、/etc/init.d/mountnfs.sh だという事がわかりました。このファイルを辿って行くと、"$ASYNCMOUNTNFS" という変数を見て、do_wait_async_mount に飛ぶか飛ばないかを見ているようです。どうもこいつが怪しそうです。

結局以下のコマンドを打ったら、現象は再現しなくなりました。根本的な原因はよくわかりませんが、まあいいかなと...
`echo "ASYNCMOUNTNFS=no" >> /etc/default/rcS`