x86でfloatの精度で桁落ちさせるには
前回、起こるはずの桁落ちが起こらない不思議現象の原因を特定した。
ではx86では単精度浮動小数点数の精度で桁落ちを起こすことはできないのだろうか。実は案外簡単にできる。SSEを使えばいいのだ。試しに前回のソースをSSEを使うようにしてコンパイルしてみよう。
実行結果
前回赤で示した部分に対応するアセンブラ
なるほど根はfpuの方でとってるのな。まぁさすがにdoubleの部分まで単精度で計算しちゃったらまずいよなぁ。
-mfpmath=sseは浮動小数点数の基本演算の方法としてsseのみを使うように指定するもので、浮動小数点数が1つしかなくてもSIMD命令を使うという素敵なコードを吐いてくれる。Pentium3で実装された初期からのSSE命令は32bit単精度浮動小数点数しか扱うことが出来ないので望み通り単精度浮動小数点数の精度で桁落ちしてくれる。
ちなみに倍精度に対応したり命令が増えたりなSSE2にしてみたところ、
実行結果
前回赤で示した部分に対応するアセンブラ
なんて都合の良い命令なんだ。
青で示したところで単精度浮動小数点数を倍精度浮動小数点数にキャストして、赤で示したところで根を取る。全部SSEでやっているようだ。なんだかんだでx86も色々改良されてるんだなぁ。
おまけ: もっと簡単にできた。
実行結果
-ffloat-storeを付けると68kやx86のような浮動小数点数の精度毎に命令をわけていないCPU上で、浮動小数点数の精度にうるさいプログラムが意図した動作をするようにするらしい。どういう仕組みかはなんとなく名前から想像が付くが、いちおう前回赤で示した部分に対応するアセンブラを確認してみよう。
やはり1回計算するたびにストアしてロードしているようだ。これは効率が悪そうだ... 実際に使うときは本当にSSEではなくこちらを使って精度を制限する必要があるかどうかよく考えた方が良さそうだ。
ではx86では単精度浮動小数点数の精度で桁落ちを起こすことはできないのだろうか。実は案外簡単にできる。SSEを使えばいいのだ。試しに前回のソースをSSEを使うようにしてコンパイルしてみよう。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
float hoge = 1.0e-9;
float piyo = 3.0;
printf( "%e\n", piyo - sqrt( piyo * piyo - hoge ) );
}
gcc -o sample -msse -mfpmath=sse -fno-math-errno sample.c
実行結果
0.000000e+00
前回赤で示した部分に対応するアセンブラ
8048371: f3 0f 59 45 f8 mulss 0xfffffff8(%ebp),%xmm0
8048376: f3 0f 5c 45 f4 subss 0xfffffff4(%ebp),%xmm0
804837b: f3 0f 11 45 e8 movss %xmm0,0xffffffe8(%ebp)
8048380: d9 45 e8 flds 0xffffffe8(%ebp)
8048383: d9 fa fsqrt
なるほど根はfpuの方でとってるのな。まぁさすがにdoubleの部分まで単精度で計算しちゃったらまずいよなぁ。
-mfpmath=sseは浮動小数点数の基本演算の方法としてsseのみを使うように指定するもので、浮動小数点数が1つしかなくてもSIMD命令を使うという素敵なコードを吐いてくれる。Pentium3で実装された初期からのSSE命令は32bit単精度浮動小数点数しか扱うことが出来ないので望み通り単精度浮動小数点数の精度で桁落ちしてくれる。
ちなみに倍精度に対応したり命令が増えたりなSSE2にしてみたところ、
gcc -o sample -msse2 -mfpmath=sse -fno-math-errno sample.c
実行結果
0.000000e+00
前回赤で示した部分に対応するアセンブラ
8048373: f3 0f 59 45 f8 mulss 0xfffffff8(%ebp),%xmm0
8048378: f3 0f 5c 45 f4 subss 0xfffffff4(%ebp),%xmm0
804837d: f3 0f 5a c0 cvtss2sd %xmm0,%xmm0
8048381: f2 0f 51 c0 sqrtsd %xmm0,%xmm0
なんて都合の良い命令なんだ。
青で示したところで単精度浮動小数点数を倍精度浮動小数点数にキャストして、赤で示したところで根を取る。全部SSEでやっているようだ。なんだかんだでx86も色々改良されてるんだなぁ。
おまけ: もっと簡単にできた。
gcc -o sample -ffloat-store -fno-math-errno sample.c
実行結果
0.000000e+00
-ffloat-storeを付けると68kやx86のような浮動小数点数の精度毎に命令をわけていないCPU上で、浮動小数点数の精度にうるさいプログラムが意図した動作をするようにするらしい。どういう仕組みかはなんとなく名前から想像が付くが、いちおう前回赤で示した部分に対応するアセンブラを確認してみよう。
8048372: d8 4d f4 fmuls 0xfffffff4(%ebp)
8048375: d9 5d d0 fstps 0xffffffd0(%ebp)
8048378: d9 45 d0 flds 0xffffffd0(%ebp)
804837b: d8 65 f0 fsubs 0xfffffff0(%ebp)
804837e: d9 5d d4 fstps 0xffffffd4(%ebp)
8048381: d9 45 d4 flds 0xffffffd4(%ebp)
8048384: dd 5d d8 fstpl 0xffffffd8(%ebp)
8048387: dd 45 d8 fldl 0xffffffd8(%ebp)
804838a: d9 fa fsqrt
やはり1回計算するたびにストアしてロードしているようだ。これは効率が悪そうだ... 実際に使うときは本当にSSEではなくこちらを使って精度を制限する必要があるかどうかよく考えた方が良さそうだ。
FPU
大学の講義で桁落ちによる誤差を説明するために二次関数の解の公式を用いた例が使われた。
IEEE754の単精度浮動小数点数の係数部は24bitで、10進数にしてせいぜい7-8桁しか表現できない。そのため、sqrtが呼び出される前に4acが消えてしまい、bの2乗の根でsqrtの結果がbになり、result[ 1 ]の結果が実際には非常に小さな非ゼロ値になるにもかかわらず0が出る、というもの。
ところが
実行結果
非ゼロ値が出た。
当初doubleを引数に取るsqrtを用いたことが原因ではないかと考えたが、C言語の結合規則が守られている限りfloatからdoubleへキャストするときには既に桁落ちが発生している。
何が起こったのだろう。
詳しく調べる前に理解に苦しむ挙動をしている部分だけを取り出してみた
実行結果
ちなみにhogeを1.0e-16にすると期待どおり結果が0.000000e+00になってくれるが、これは明らかにfloatの精度ではない。
とりあえず逆アセンブルしてみよう。
するとgccが壮絶なコードを吐いていた事実が判明する。まず青で示した位置にsqrtの呼び出しがあるのだが、注目すべきはそれより上の赤で示した部分だ。どうやらgccはまずx87FPU内にあるfsqrt命令で済まそうと試み、それがうまくいかなかった場合だけC言語から直感的に予想のつくsqrt関数の呼び出しを行うというコードを吐いたらしい。
ちなみに-fno-math-errnoを付けてコンパイルするとFPUのステータスレジスタをチェックしなくなり、中程のsqrt関数を呼び出して計算する方の命令が綺麗に無くなった。sqrtを呼ばないんだから、と-lmを外してみたところそのままlibmを使用しないで動くバイナリが出来上がった。
さて、x87は歴史的な理由からx86から独立したレジスタを持っている。x87内の8つのレジスタは全て80bit拡張倍精度浮動小数点数を入れるようになっており、メモリから持ってきた値が32bitだろうと64bitだろうと80bitに延ばしてレジスタに読み込まれる。そして、命令の最後にsやl、d等が付いていても全ての演算は80bit拡張倍精度浮動小数点数同士で行われる(つまり少なくともx86ではdoubleをfloatにしてもデータ転送の速さに差が出る可能性はあっても演算の速さは全く変わらない)。これはつまり、レジスタ上で完結したデータ転送を伴わない計算の間は80bit拡張倍精度浮動小数点数の精度で値が保持されるということだ。
先ほどのアセンブリの赤の部分をもう一度見てみよう。乗算(fmul)をしたあと(fsub)してここで結果を倍精度浮動小数点数としてストアしてすぐロードしている。おそらく倍精度浮動小数点数で表現できない範囲を捨てることでdoubleにキャストしたことにしているのだろうが、行われたのはC言語プログラマが期待した32bitから64bitへのキャストではない。80bitから64bitへのキャストだ。そしてx87の便利命令sqrtが1命令で根を計算する。
このように肝心な部分で期待した精度より高い精度で計算が行われたために、計算中に発生してほしかった桁落ちが発生しなかったというのが意図しない実行結果の原因のようだ。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
float a = 1.0e-9f;
float b = 3.0f;
float c = 1.0f;
float result[ 2 ];
result[ 0 ] = ( b + sqrt( b * b - 4 * a * c ) ) / 2;
result[ 1 ] = ( b - sqrt( b * b - 4 * a * c ) ) / 2;
printf( "%e, %e", result[ 0 ], result[ 1 ] );
exit( EXIT_SUCCESS );
}
IEEE754の単精度浮動小数点数の係数部は24bitで、10進数にしてせいぜい7-8桁しか表現できない。そのため、sqrtが呼び出される前に4acが消えてしまい、bの2乗の根でsqrtの結果がbになり、result[ 1 ]の結果が実際には非常に小さな非ゼロ値になるにもかかわらず0が出る、というもの。
ところが
実行結果
3.000000e+00, 3.333334e-10
非ゼロ値が出た。
当初doubleを引数に取るsqrtを用いたことが原因ではないかと考えたが、C言語の結合規則が守られている限りfloatからdoubleへキャストするときには既に桁落ちが発生している。
何が起こったのだろう。
詳しく調べる前に理解に苦しむ挙動をしている部分だけを取り出してみた
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
float hoge = 1.0e-9;
float piyo = 3.0;
printf( "%e\n", piyo - sqrt( piyo * piyo - hoge ) );
}
実行結果
1.666667e-10
ちなみにhogeを1.0e-16にすると期待どおり結果が0.000000e+00になってくれるが、これは明らかにfloatの精度ではない。
とりあえず逆アセンブルしてみよう。
080483d0 <main>:
80483d0: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483d4: 83 e4 f0 and $0xfffffff0,%esp
80483d7: ff 71 fc pushl 0xfffffffc(%ecx)
80483da: 55 push %ebp
80483db: 89 e5 mov %esp,%ebp
80483dd: 51 push %ecx
80483de: 83 ec 44 sub $0x44,%esp
80483e1: b8 5f 70 89 30 mov $0x3089705f,%eax
80483e6: 89 45 f0 mov %eax,0xfffffff0(%ebp)
80483e9: b8 00 00 40 40 mov $0x40400000,%eax
80483ee: 89 45 f4 mov %eax,0xfffffff4(%ebp)
80483f1: d9 45 f4 flds 0xfffffff4(%ebp)
80483f4: dd 5d d8 fstpl 0xffffffd8(%ebp)
80483f7: d9 45 f4 flds 0xfffffff4(%ebp)
80483fa: d8 4d f4 fmuls 0xfffffff4(%ebp)
80483fd: d8 65 f0 fsubs 0xfffffff0(%ebp)
8048400: dd 5d e0 fstpl 0xffffffe0(%ebp)
8048403: dd 45 e0 fldl 0xffffffe0(%ebp)
8048406: d9 fa fsqrt
8048408: dd 5d d0 fstpl 0xffffffd0(%ebp)
804840b: dd 45 d0 fldl 0xffffffd0(%ebp)
804840e: dd e8 fucomp %st(0)
8048410: df e0 fnstsw %ax
8048412: 9e sahf
8048413: 7a 02 jp 8048417 <main+0x47>
8048415: 74 0e je 8048425 <main+0x55>
8048417: dd 45 e0 fldl 0xffffffe0(%ebp)
804841a: dd 1c 24 fstpl (%esp)
804841d: e8 f6 fe ff ff call 8048318 <sqrt@plt>
8048422: dd 5d d0 fstpl 0xffffffd0(%ebp)
8048425: dd 45 d0 fldl 0xffffffd0(%ebp)
8048428: dc 6d d8 fsubrl 0xffffffd8(%ebp)
804842b: dd 5c 24 04 fstpl 0x4(%esp)
804842f: c7 04 24 3c 86 04 08 movl $0x804863c,(%esp)
8048436: e8 cd fe ff ff call 8048308 <printf@plt>
804843b: 83 c4 44 add $0x44,%esp
804843e: 59 pop %ecx
804843f: 5d pop %ebp
8048440: 8d 61 fc lea 0xfffffffc(%ecx),%esp
8048443: c3 ret
するとgccが壮絶なコードを吐いていた事実が判明する。まず青で示した位置にsqrtの呼び出しがあるのだが、注目すべきはそれより上の赤で示した部分だ。どうやらgccはまずx87FPU内にあるfsqrt命令で済まそうと試み、それがうまくいかなかった場合だけC言語から直感的に予想のつくsqrt関数の呼び出しを行うというコードを吐いたらしい。
ちなみに-fno-math-errnoを付けてコンパイルするとFPUのステータスレジスタをチェックしなくなり、中程のsqrt関数を呼び出して計算する方の命令が綺麗に無くなった。sqrtを呼ばないんだから、と-lmを外してみたところそのままlibmを使用しないで動くバイナリが出来上がった。
さて、x87は歴史的な理由からx86から独立したレジスタを持っている。x87内の8つのレジスタは全て80bit拡張倍精度浮動小数点数を入れるようになっており、メモリから持ってきた値が32bitだろうと64bitだろうと80bitに延ばしてレジスタに読み込まれる。そして、命令の最後にsやl、d等が付いていても全ての演算は80bit拡張倍精度浮動小数点数同士で行われる(つまり少なくともx86ではdoubleをfloatにしてもデータ転送の速さに差が出る可能性はあっても演算の速さは全く変わらない)。これはつまり、レジスタ上で完結したデータ転送を伴わない計算の間は80bit拡張倍精度浮動小数点数の精度で値が保持されるということだ。
先ほどのアセンブリの赤の部分をもう一度見てみよう。乗算(fmul)をしたあと(fsub)してここで結果を倍精度浮動小数点数としてストアしてすぐロードしている。おそらく倍精度浮動小数点数で表現できない範囲を捨てることでdoubleにキャストしたことにしているのだろうが、行われたのはC言語プログラマが期待した32bitから64bitへのキャストではない。80bitから64bitへのキャストだ。そしてx87の便利命令sqrtが1命令で根を計算する。
このように肝心な部分で期待した精度より高い精度で計算が行われたために、計算中に発生してほしかった桁落ちが発生しなかったというのが意図しない実行結果の原因のようだ。
メモ
x86版
PowerPC版
#include <iostream>
#include <stdexcept>
#include <dlfcn.h>
extern "C" void initSqrt();
double (*sqrt)( double ) = (double (*)( double ))(void*)( &initSqrt );
extern "C" void loadSqrt() {
void *handle = dlopen( "libm.so", RTLD_LAZY );
if( !handle )throw std::domain_error( "Unable to load libm" );
sqrt = (double (*)( double ))dlsym( handle, "sqrt" );
if( !sqrt ) {
sqrt = (double (*)( double ))(void*)( &initSqrt );
dlclose( handle );
throw std::domain_error( "Unable to find sqrt" );
}
}
__asm__ __volatile__ (
" .section .bss\n"
" .align 4\n"
"external_ebp: .type external_ebp, @object\n"
" .size external_ebp, 4\n"
" .text\n"
"initSqrt:\n"
" mov %ebp, external_ebp\n"
" mov %esp, %ebp\n"
" call loadSqrt\n"
" mov external_ebp, %ebp\n"
" jmp *sqrt"
);
int main() {
std::cout << sqrt( 2.0 ) << std::endl;
}
PowerPC版
#include <iostream>
#include <stdexcept>
#include <dlfcn.h>
extern "C" void initSqrt();
double (*sqrt)( double ) = (double (*)( double ))(void*)( &initSqrt );
extern "C" void loadSqrt() {
void *handle = dlopen( "libm.so", RTLD_LAZY );
if( !handle )throw std::domain_error( "Unable to load libm" );
sqrt = (double (*)( double ))dlsym( handle, "sqrt" );
if( !sqrt ) {
sqrt = (double (*)( double ))(void*)( &initSqrt );
dlclose( handle );
throw std::domain_error( "Unable to find sqrt" );
}
}
__asm__ __volatile__ (
" .section .bss\n"
" .align 2\n"
"external_ebp: .type external_ebp, @object\n"
" .size external_ebp, 4\n"
" .text\n"
"initSqrt:\n"
" mflr 11\n"
" lis 12, external_ebp@ha\n"
" stw 11, external_ebp@l(12)\n"
" bl loadSqrt\n"
" lis 12, external_ebp@ha\n"
" lwz 11, external_ebp@l(12)\n"
" mtlr 11\n"
" lis 11,sqrt@ha\n"
" lwz 11,sqrt@l(11)\n"
" mtctr 11\n"
" bctr"
);
int main() {
// sqrt( 2.0 );
std::cout << sqrt( 2.0 ) << std::endl;
}
PerlでXML
設定ファイルというのはいつの時代も悩ましいもののようで、昔から色々なフォーマットが考えられてきた。initrdのフォーマット、Makefileのフォーマット、httpd.confのフォーマット... 技術者は新しいソフトウェアに遭遇するたびにそれらの独自の文法を学ばなければならないのだろうか。
こうした問題に対処するために、用途に特化せず汎用的にデータ構造を表現するためのフォーマットとして考案されたのがXMLだ。
さて、XMLをパースする為のライブラリはオープンソースな実装だけでもいくつか存在するが、うちはC++が好きなのでQtのXMLパーサを使おうと考えドキュメントを調べ、その壮絶な実装に目が点になるわけだ。
XMLを操作するためのインターフェースとしては逐次読み込みで処理するSAXと一度全てメモリにダンプしてから処理するDOMという2種類の実装が標準となっているのだが、どちらの実装もシンプルな改行で区切られた設定ファイルの読み込みと比較すると信じられないほど大きい。ほんの10行程度の簡単なXMLを操作するためにこんな複雑な手順を踏まなければならないのだろうか。
と、ここでふとPerlに目を向けると
XML::Simple
名前からしてシンプルそうなXMLパーサが存在することに気付く。使いかたは以下の通り。
とりあえずXML::Simpleを使えるようにして
新しいハンドラを作って
読み込むと
データ構造がそのままハッシュになっていて
値を書き換えたら文字列変数に書き出す。
中身を全部見たいときは
細かいオプションが色々あるけど基本的な使いかたはこれだけ。
簡単だ...
こうした問題に対処するために、用途に特化せず汎用的にデータ構造を表現するためのフォーマットとして考案されたのがXMLだ。
さて、XMLをパースする為のライブラリはオープンソースな実装だけでもいくつか存在するが、うちはC++が好きなのでQtのXMLパーサを使おうと考えドキュメントを調べ、その壮絶な実装に目が点になるわけだ。
XMLを操作するためのインターフェースとしては逐次読み込みで処理するSAXと一度全てメモリにダンプしてから処理するDOMという2種類の実装が標準となっているのだが、どちらの実装もシンプルな改行で区切られた設定ファイルの読み込みと比較すると信じられないほど大きい。ほんの10行程度の簡単なXMLを操作するためにこんな複雑な手順を踏まなければならないのだろうか。
と、ここでふとPerlに目を向けると
XML::Simple
名前からしてシンプルそうなXMLパーサが存在することに気付く。使いかたは以下の通り。
とりあえずXML::Simpleを使えるようにして
use XML::Simple;
新しいハンドラを作って
my $hoge = XML::Simple->new();
読み込むと
my $data = $hoge->XMLin( '/path/to/file.xml' );
データ構造がそのままハッシュになっていて
print $data->{foo}->{hoge}->{piyo}, "\n";
値を書き換えたら文字列変数に書き出す。
my $str = $hoge->XMLout( $data );
中身を全部見たいときは
use Data::Dumper;
print Dumper($data) . "¥n";
print Dumper($data) . "¥n";
細かいオプションが色々あるけど基本的な使いかたはこれだけ。
簡単だ...
nanorc
密かに大学のLinux環境にnanoが入っていたので家のnanorcを持ち込んでみる。
中身は基本的にgentoo流のnanorc。
nanoのcolor syntaxの設定がめんどくさい人はこれをこのまま使うと楽かもしれない。
nanorcの配置はシステム全体に適用するときは/etc/nanorc、個人で使う場合は~/.nanorc。
中身は基本的にgentoo流のnanorc。
nanoのcolor syntaxの設定がめんどくさい人はこれをこのまま使うと楽かもしれない。
nanorcの配置はシステム全体に適用するときは/etc/nanorc、個人で使う場合は~/.nanorc。
begin 664 nanorc.bz2
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
H@,Z(7M!H_L:^.)55;Y8MP>GAT*+;!ZC'%F<YR#_Q=R13A0D-$LG/,```
`
end
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
H@,Z(7M!H_L:^.)55;Y8MP>GAT*+;!ZC'%F<YR#_Q=R13A0D-$LG/,```
`
end