Perlテックブログ

ITエンジニアの成長意欲を刺激する技術考察、モジュール開発の日記。Perlイベントや国内や海外のPerlの記事の紹介。

values型を実装して複素数を扱えるようにする

SPVMの残っている課題の中に、どうやって複素数複素数の配列を扱うかというものがある。

複素数と一言にいっても、持っている数値型は複数考えられる。int32_t, int64_t, float, double型をフィールドに持つとすると、これで4種類。

参照型が遅い理由

単純に考えるのであれば、参照型で持てばよいのではと思うかもしれない。

# 参照型のdouble複素数
package Complex_double {
  has re : double;
  has im : double;
}

しかし参照型は、遅いのである。特に複素数のような小さなデータに対しては、コストが大きい。

遅い理由は

  • ひとつの複素数ごとに、オブジェクトを生成する必要がある
  • 配列にしたときに、オブジェクトがメモリ上でとびとびになっているのでアクセスが遅い
  • フィールドにアクセスするときに、名前解決などの処理が必要

参照型しかなければ、たぶん複素数の高速な計算を実現できないだろう。

values型を実装するアイデア

ここが、一番難しいところなんだけれど、values型というものを実装する予定でいる。なぜ難しいかというと、他の言語に存在しないので、完全に自分でデザインしないといけないから。

そして、今まで存在しないということは、それがそもそも実現できないからやられていないのか、たまたま存在していないだけなのかわからないということだ。

この点ではJavaを参考にすることができない。バイトコードを実行する言語で、値型を持つ言語実装の参考例がない。(Javaで実験的には、試されているようではあるけれど)

今考えているアイデアをここに記しておく。

values型の定義

values型の定義は次のようになる。

package Complex_double_2 : values {
  has re : double;
  has im : double;
}
  • valuesというデスクリプタでvalues型であることを示す
  • values型の名前には数値型とフィールドの個数が含まれていなければならない
  • フィールドには、byte, short, int, long, float, doubleという数値型の値だけを持つことができる
  • フィールドには同じ型の数値型を複数宣言する必要がある
  • フィールドの個数の最大値は、引数の最大値と同じ255個まで

Complex_double_2のように型名の中に、数値型と個数が入っていなければいけないのは、もし、フィールドが追加されしまったときに、プログラムがエラーを検知できず、メモリを破壊してしまう可能性があるためだ。数値型と個数が型名に含まれていれば、それを検出できる。

CレベルAPIでは、引数の中で、複数の数値型に展開される

C言語で、引数を受け取るときは、複数の数値型に自動的に展開される。

double re = stack[0].dval;
double im = stack[1].dval;

SPVMのレベルでは何も意識しないでよい

SPVMのレベルでは何も意識しないでよい。

my $nums = new Complex_double_2[10];
my $num : Complex_double_2;
$num->{re} = 0.5;
$num->{im} = 0.5;

$nums->[0] = $z;