#!/usr/bin/perl use Benchmark qw(cmpthese); use PDL; $m = sequence(600,600); cmpthese(10, { xchg => sub { $mm = matmult($m->xchg(0,1), $m); }, tmp => sub { $tmp = $m->xchg(0,1); $mm = matmult($tmp, $m); }, tmpcopy => sub { $tmpcopy = $m->xchg(0,1)->copy; $mm = matmult($tmp, $m); } } );
昨日 Linux 上で実験してみた PAR を Windows にも入れてみる。 PDLを使っている関係で ActivePerl は 5.6.1。
ppm install で入るパッケージは古いので、最新のものを入れておく。 ちょっと手間。
ワンライナーを pp できるところまで動作確認。
ExtUtils::Makemakerを使ってパッケージ化している開発中のモジュール(スクリプトあり、XS あり)を実行可能形式化してみる。
perl Makefile.PL nmake nmake test cd blib set PERL5LIB=lib;arch (pp の -I オプションが効かなかったので) pp -o foo.exe -a lib -a arch -M ... -c script/foo
Log::Log4perl::Appender::Screen、Jcode::Unicode::NoXS、Unicode::String、GD については依存関係を自動検出できなかったので、それぞれ -M で指定。
できた。動いた。素晴しい。 PDL や GD を使っていたのでちょっと不安だったのだがうまく動いて感激。 これでCD-ROMとか USB メモリに入れておいて一発実行とかできる。
実は SourceForge.net にあった。 まだ動作確認していないが、問題なければこれで ActivePerl 5.6.1 ともおさらば。
その場合は PPM リポジトリを再構築しなおしであるが。
PDLの動作確認がとれたのでプロジェクトで使用するバージョンを v5.8.4 に上げることにする。 PPM パッケージ全部作りなおし。4時間ちょいかかった。
ついでに ithreads まわりもチェック。
PDL は bad value を扱うことができるのだが、どの程度速度に影響がでるであろうか。 ベンチマークを取ってみた。 環境は Debian GNU/Linux sid + pdl 2.4.2-2 + 2672-PHJ。
#!/usr/bin/perl -w use strict; use PDL; use Benchmark; my $a = sequence(1000, 1000); my $b = sequence(1000, 1000); #$a->badflag(1); #$b->badflag(1); timethis(10, sub { my $c = matmult($a, $b)});
badflag(0)
timethis 10: 203 wallclock secs (198.90 usr + 0.46 sys = 199.36 CPU) @ 0.05/s (n=10)
badflag(1)
timethis 10: 416 wallclock secs (400.87 usr + 0.92 sys = 401.79 CPU) @ 0.02/s (n=10)
ほぼ半分の速度。 ちなみに bad value サポート無しで PDL をリビルドして試してみたが、bad value 無しの計算では(matmult においては)特に差がなかった。
bad value の必要がないならば、PDL をリビルドした方がいいのかと思ってみたけれど実験した範囲ではかわらないようだ。
PDL を使用しているプログラムの高速化のため、再び PDL::PP でコードを書こうとマニュアルを見直したりしている。
PDL::PP にも Inline 系の Inline::Pdlpp モジュールが用意されているのか。 PDL::PP の仕様は結構わかりにくくて(かなり)慣れないと大変。 何度も書いてはテストしてみることになるので、そういった意味でも Inline できるのはすごい便利。
Inline::Pdlpp で関数ができあがったら 整理して PDL::Core::Dev のサポートのもとで Makefile.PL を書くようにすれば、いっちょあがり。
最近急に RDBMS に興味をもってきた。 といっても、できればライトなやつ。
Perl と相性が良さそう。SQLite はコードが少なく public domain なので、DBI用ドライバモジュール DBD::SQLite は SQLite のコードを全部取り込んでしまってある。 ActivePerl 5.8.6.811でもビルドできた。
PDLのベクトルを Storable (PDL::IO::Storable)でシリアライズして SQLite 保存し、後で必要な時に取り出しアンシリアライズして計算に使うっていう風にしたいんだけれど速度的にどうなんだろう。 要実験。
別件。 Oracle Database にアクセスする Java アプリケーションのテスト方法を思案中。 モックオブジェクトを使う方法も考えたけれど、やはり実環境に近い方がいいんじゃないだろうか。
となると DbUnit あたり?
そのうち設定してみるか。 開発者ごとにデータベースを作らねばならないな。
PDL を使っている Perl プログラムを、昨日構築した今ごろの環境で PAR を使って実行可能ファイル化したんだけれども、実行してみたら
Can't locate loadable object for module PDL::Core in @INC ...
というエラー。 実行時のキャッシュディレクトリを見ると core.dll が同梱されていない模様。 なんでだー。
いろいろやってみたところ、もしやと思ってインストール済みの core.dll を Core.dll という名前に変えたらエラーが出なくなった(正確には次のモジュールで同様のエラーが出た)。
ファイル名の大文字・小文字が問題だったらしい。 PAR の FAQ には「Win32::Perms の Perms.DLL でこのエラーが出たら、Perms.dll にしてね」と書かれている。 最初これ拡張子の問題だけだと思っていた。 ベース名でも同様のようだ。
以前は問題なかったから、比較的新しい PAR で発生するようになったと思われる。 これ絶対はまる。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。