前回のアルファ版リリースから早くも一カ月が過ぎ去ろうとしていますが、ドキュメントやテストプログラムをちまちま書こうかと思っていたのですが、どうしてもある機能を入れたくて現在鋭意作成中です。
その機能とはキャッシュ機能になるのですが、つまりDBから値を取り出してそのままメモリに保持する機能なのですが、それが通常述語の評価(つまりSQLの発行)と透過的に行われれば幸せになるかと思ってます。
触発されたのは、ちょっと前の記事になりますが、以下のMixiの障害です。
『mixi』のアクセス障害のお詫び及び復旧に関するお知らせ
2週間前の障害ですが、原因はmemcachedと呼ばれる分散型のメモリキャッシュシステムらしいです。大規模システムではこのようなキャッシュが良く使われているらしいです。
私自体はmemcachedは使用したことは無いですが、キャッシュの必要性は理解しておりますし、SQLの実行パフォーマンスについて 2010で書いているとおりオンメモリで処理を行うことによりパフォーマンスが上がるケースもあると指摘しておりましたが、ADPでは、もっと簡単にキャッシュが使えたらなということで、キャッシュ機能をサポートします。
もっともちょっと難航しておりまして、わざわざこのように『次回リリース予定の機能』と書いたのは自身のモチベーションを上げる為だったりします。
[ADP開発日誌]Ver0.5アルファ版 リリース
ADPの開発版(Ver0.5)をリリースしました。
SourceForge.JPにてリリースしております。GPLで公開します。
以下のページからソースおよびプロジェクトファイルがダウンロードできます。
http://sourceforge.jp/projects/adp/
以前、[ADP開発日誌]ソースコードを公開するか?でソースは公開しないと言っていましたが、結局ソースで公開します。Windows版の方はバイナリ版も公開しています。
理由ですが、知人にMacOSXでコンパイルして頂いたのですが、コンパイル自体は通ったということで案外移植性が高いソースのようで、『ならばソース公開していろんな人に使ってもらった方がよいな』ということで公開しました。
実際に触りだすとあれやこれや色々いじりたくなり、そういう意味ではソース公開してちょこちょこリリースした方が活動状況も解ってよいかなというのもあります。まぁ何はともあれ後はドキュメントとサンプル(とテストプログラム)に集中したいのですが、またソース修正したりするかもしれません・・・。
P.S. Mさんへ、GitHubではなくてSourceForge.JPで公開でしました。GitHubも考えたのですが、諸事情によりSourceForge.JPの方が使いやすかったのでとりあえずこちらで公開しましたです。せっかく教えて頂いたのですがすみませんです。
[ADP開発日誌]経済ゲームを作ってみよう
最近ADP関連のブログの更新がありませんでしたが、久しぶりのADPの布教活動を。
今年も飛び交う「日本みたいになるぞ」報道に書かれていますが、日本の失われた10年は海外でも悪い見本と取られていますが、もっと驚くことに、引用しますと、
デフレというおなじみのお化けがアメリカ経済の懸念材料として再登場している。(中略)日本のデフレを10年以上も研究した結果、エコノミストたちは次第に、自分たちはデフレの仕組みを何も分かっていないと気づき始めている
にありますとおり、デフレの仕組が解っていない事実に、なるほどと思うとともに『エコノミストは何をやっとんのじゃ!』というある種の憤りを感じたりする。特にソフトウェアエンジニアはコンピュータが動かないとお客からのある種のプレッシャーを感じるのだが、『エコノミストは、この日本の状況下である種の責任感とか使命感とかには駆られないのだろうか?』とか色々考える。
もっとも多くの人も何かおかしいということに気づいているかとは思うのですが、『ではどうやって解決するの?』と思われるでしょう。そ・こ・で、ADPの登場です!(ってかなり強引な宣伝です)。つまり、あ~だ、こ~だと議論ばかりに頼らずにもっと科学的にシミューレーションのような手法を使ってデフレのメカニズムの解明とかの研究をしませんか?という提案です。
ADPですが、Another Data Processorの名前のとおり、経済シミュレーションのようにややこしいシステム(真面目な言葉を使えば複雑系)を容易に記述できるようにというコンセプトで開発を行っています。
サンプルでちょっとした経済ゲームを作成してみました。
ソースも添付しましたので参照して頂ければ解るかと思いますが、様々な条件や計算を行うシステムでも比較的スッキリと記述できるかと思います。
ちなみに、ゲーム自体は興味本位で作成したのですが、作成したモデルですが、製品を無限に作成できる場合、人口は安定的に増える。ので上限を設けたら、今のところ安定的に人口増加するパラメータが見つかっていません。見つけた人は連絡を!
freshmeat
ADPの布教活動の一環ですが、freshmeatというソフトウェアの告知サイトがあったので登録しました。
ADP | freshmeat.net
freshmeat自体は、オープンソースへの参加は難しくない(5)作ってみる 前編 で知りました。freshmeatのサイトは英語が使われているのですが、なかなか親切なサイトで、以下のように私のつたない英語を修正してもらえました。
『ADP (Another Data Processor) is a programing language is designed for Web database programing. It is a scripting language and a lightweight programming language in which it is possible to mix SQL easily. It is easy to install.』
ちなみに元の英文は・・・まぁやめましょう。
C++/STL 1GBのintのソートにかかる時間 2010
未踏の説明会の続きですが、説明会の中に技術的なセッションもありまして、グーグル株式会社のソフトウェアエンジニア 鵜飼さんの講演が面白かったのですが、その中で、『1GBのintのソートにかかる時間は、封筒の裏計算で、30秒』というのがありました。
パフォーマンスには一家言ある私ですが、さすがに1GBのintのソート時間にはピンと来ませんでした。
という訳で、ホントかどうかやってみました。
#include <vector>
#include <algorithm>
#include <iostream>
#include <time.h>
using namespace std;
int main(void)
{
vector values;
srand(time(0));
// vectorに適当な値を入れる
for ( int i = 0; i < 1024*1024*1024 / sizeof(int); i++ ) {
values.push_back((int)(rand()*rand()-i));
}
// ソートする
clock_t t = clock();
sort( values.begin(), values.end());
cout << "Time(sort) is "
<< (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;
return 0;
}
実行時間(Core i7-920 Windows7 コンパイルVC++2008 リリースモード 64ビットモード)は以下になります。上記のプログラムですが、32ビットモードでは動作しません。32ビットプロセスはリニアに1GBのメモリは確保できないです。
Time(sort) is 43.895sec.
なるほど、確かに30秒からそう離れていません。
ちなみに、この手の封筒の裏計算ですが、桁が違わなければOKと考えてよいでしょう。なので、細かい値の違いが問題になる場合は、実アプリでキチンとベンチマークをとるのがよいでしょう。
この手の結果の受け止め方ですが、おそらく一般の業務アプリを作成する人にとっては『理論的限界値』程度に思っていた方がよいでしょう。つまり
1秒間に数百万個のint型のソートができる。数千万個になったら要注意。
と思っておけばよろしいかと思います。実際に私の経験でも行数が数百万件のソートをSQLで行うのはあまり問題になることはなかったです。(もちろんメモリが十分にあればの話ですが)。
実行時間の詳細ですが、説明では以下のとおりでした。
・要素を比較する回数(ソートのオーダnlogn)から、
2^28 * log(2^28) → 2^28 * 28 → 2^28 * 2^5 → 2^33(2の33乗)回
・比較に際してのL1キャッシュのアクセス時間 0.5ns / 回
・比較に際してのブランチペナルティ 2.5ns / 回(2回に1回ペナルティがあると仮定する)
実行時間 2^33 * (0.5 + 2.5)nsec = 25.76sec 約30秒
ただ、上記の計算ですが、ブランチペナルティが全体の速度を決定しているというのはいささか疑問があります。上記の場合、メモリのアクセス回数から計算した方が良いのでは?と思います。
つまり、
・要素を比較する回数(ソートのオーダnlogn)から、
2^28 * log(2^28) → 2^28 * 28 → 2^28 * 2^5 → 2^33(2の33乗)回
・ 比較に際してのメモリアクセス回数 2回(リード&ライト) 2*4バイト
・キャッシュライン 32バイト
・メインメモリへのアクセス回数 2^33 * 2 * 4 / 32 = 2^31 回
・メインメモリアクセス性能 1回のアクセス 10nsec(DDR3のレイテンシーから)
実行時間 2^31 * 10nsec = 21.47sec
うーん、数値的には似たり寄ったりであまり変わらないか・・・・
未踏ソフトの説明会に行ってきました
ADPを開発する上で避けて通れないのが、『どうやって流行らすか?』になります。
もっとも、自己満足と言われようが何と言われようがADPの開発は続けますし使ってもいくと思うので、流行らなくてもという良いという考えもなくもないのです。
しかし、個人でやる開発ならそれでOKなのですが、人と仕事をする上ではこの手のこだわりが障害になったりしますし、この手の複雑なソフトウェアは広く動作させてフィードバックをもらうことが品質面からも重要になります。
要するにプロのエンジニア目線で考えると、自分が作った言語とは言えマイナーなプログラミング言語にかかわっているヒマはないということになるのですが、であればメジャーにすればよいということで『流行らそう』ということになりました。
もちろん、大前提として、流行らすに値する言語かということもありますが、そのあたりについてはまたの機会に書きます。
で、具体的に何をするねんって話になるのですが、色々考えているのですが、もちろんこのブログも布教活動の一環としてやっているのですが、その1つとして、未踏ソフトに挑戦するということがあります。ちなみにその後は、LLイベント(http://ll.jus.or.jp/)にパネリストとしてADPを布教することを目標にしております。
未踏ソフトですが、以前は2008年の下期に応募したのですが、残念ながら採択にならず、その後仕事が忙しくなったので応募していなかったのですが、今年はタイミングよく応募できそうです。
そのような訳でちょっと知らなかったのが、いつからか年齢制限(というか年齢での優遇)が35歳未満になったらしく、今年40の私としては、『いまさら応募するのもな~』という思いと、制度の趣旨が『人材発掘』つまり天才を発掘しようということらしく『じゃなんで俺を選ばないの?』という訳のわからん自信とが交錯し、どうするか迷う面があるのですが、とにもかくにも人から評価を受けるというのは非常に大事なことなのではあります。で決めかねています。
説明会の内容ですが、私的には面白い内容でした。単なる制度の説明だけでなくちょっと聞けない技術的な話もありましたので、たまにはこういうイベントに参加するのも良いものだと思います。これからもやるでしょうから未踏に応募する人は一度説明会に参加されることをお勧めします。
C++ オブジェクトを new/delete するコスト
少し間があきましたが、技術ネタで。
new/deleteは、C++はもとより、最近のプログラミング言語なら当たり前のようにやる(おっとdeleteはしないか)かと思いますが、そのコストについてはついつい忘れがちになります。
ADPは、C++で作成しているのですが、オブジェクトをリサイクルするように変更したところ、実行速度が倍ぐらいに速くなった。もともとは速くするために行った訳ではないのだが意外な副産物となった。
Visutal C++ではいつのころからか(遅くともVC++ 2003以降)、newすると最終的にはWindowsのAPIが呼び出される。パフォーマンスにシビアなシステムでは、ローカル変数の定義のようにお気楽に出来るものではないかもしれない。
といっても理屈だけではなんなので、具体的にどのくらいのコストがかかるかベンチマークしてみました。
#include <iostream>
#include <vector>
#include <time.h>
using namespace std;
class myobject {
int myvalue;
public:
myobject() : myvalue(0){};
};
myobject *myobjects[10*1000*1000];
int test(int v)
{
return v * 1000;
}
int main(void)
{
clock_t t = clock();
// new(1千万回)
t = clock();
for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
myobjects[i] = new myobject();
}
cout << "Time(new) is "
<< (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;
// delete(1千万回)
t = clock();
for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
delete myobjects[i];
}
cout << "Time(delete) is "
<< (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;
// 関数呼出し(1千万回)
t = clock();
for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
test(i);
}
cout << "Time(function call) is "
<< (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;
return 0;
}
以下、実行結果(Core i7-920 Windows7 コンパイルVC++2008 デバッグモード)
Time(new) is 2.065sec. Time(delete) is 2.35sec. Time(function call) is 0.26sec.
Windows環境でC++だと、おおむね1秒間に約数百万個のオブジェクトが作れるようです。また、関数呼び出しは数千万回できるようです。
上記の実行結果はデバッグ環境で行っていますので、リリースモードで実行するとこれから数倍速くなります。
この手の数字にピンとこない人の為に補足しますと、最近のコンピュータは1秒間に数十億個の命令が実行できます。単純に計算しますと、メモリの確保は約千個の命令を使っており、関数呼び出しは約百個の命令を使うということになります。
[ADP開発日誌]配布イメージ
ADPはしばらくバイナリ(実行ファイル)の提供を行います。
パッケージ(インストーラやRPM等)は、そこまで開発を行う余裕がないというのもありますが、何より実行ファイルをコピーしたら使えるようにするというコンセプトで作っています。
Linuxのユーザにはちょっとお粗末な配布形式だと思われるかと思いますが、
MS-DOSからのユーザは昔からなじみのある配布形式かと思います。
[ADP開発日誌]ソースコードを公開するか?
公開するにあたって一番の悩みどころが
ソースコードをオープンにするかどうか?
というジレンマがあります。
本来ならオープンにすべきだと思うのですが以下の点からしばらくはソースコードは非公開しようかと思ってます。
- ソースが汚いので書き直す可能性が高い
- 一度公開すると非公開にできない。(逆は出来る)
- 言語仕様を出来るだけ文書化して開発したい。のでソースを公開することでお茶を濁したくない。
とまぁこんなところです。
ソースを公開しない欠点ですが、Linuxの対応になります。バイナリ配布すると各ディストリビューションの数だけそろえることになり、それは現実問題不可能なので当面は2,3のディストリビューションのみのリリースになります。
2010/08/03 追記
と言いつつ、GPLで公開しました。
[ADP開発日誌]Windows開発版のプレ公開(2)
先日プレ公開した開発版ですが、さっそくバグが見つかりましたのでアップデート版(Ver 0.4.0129)をプレ公開します。
ドキュメントを作成し、サンプルプログラムを動かしている訳ですが、each述語でバグが見つかりました。
ADPのドキュメントページをADP(正確にはADPのWEBページ拡張)で構築しているのですが、やはりというかなんというか細かいバグおよび仕様変更を行っており、まだまだ改修をしています。
ので、このあたりはお含みおき頂ければと思います。