キーを2つ持つコンテナ

クラシファイアシステムをプログラミングしている際に、
(ID・優先度・中身)を管理してくれるコンテナがほしくなったので探してみた。
機能として
・優先度の順にアクセス
・IDで検索
がほしい。


この2つの機能のどちらかなら、
キーを持つコンテナライブラリであるSTLのmultisetがこなしてくれる。
しかし、2つの機能を同時に達成することは出来ない。
即ち、キーを優先度に設定するとIDで検索は出来ないし、
キーをIDに設定すると優先度の順にアクセスは出来ないといった、
ジレンマ状況に陥る。


誰かがすでに作っていると思うので、探そうにも、
使いやすそうなSTL以外のコンテナライブラリを見つけることすら出来ない。
自作のコンテナを作るには、気力とスキルが足りない。


仕方ないので、キーを優先度に設定して、検索の際は順に調べるようにして妥協。
素数が100程度と少なく、全く影響ないとはいえ、何か悔しいなぁ。

UML設計ツール


Jude(ユダでなく、ジュード)といわれるツールでUMLを書いてみた。
UMLは簡単に言うとモデリング手法。
ちゃんと引用すると、「オブジェクト指向のソフトウェア開発における、プログラム設計図の統一表記法」。

Jude/Communityは国産のフリーのツールで、使い易かった。
Judeを使って描いたのは、右図のようなオブジェクト図。
下図が元ネタで、経済産業省が作ったものづくり白書2007の一部。


GIFアニメ

動きのあるシミュレーションをパワーポイントに載せたかったので、GIFアニメを作成した。
頻繁に動くものだと、動画撮影ソフトを使うのが良いのだけども、
今回の対象は簡単なものだったので、扱い易くサイズの小さいGIFアニメを使った。

  1. まず、WinShotを使って、シミュレーション画面(スクリーンショット)を、撮り溜めする。
  2. 次に、PhotoShifferを使って、スクリーンショットから、いらない部分を取り除く。
  3. 最後に、Giamを使って、画像を一枚のアニメーションに落とし込む。

作業も原理も簡単なので、一度やってしまえば、すぐ出切るのだけど、
画像ファイルのクリッピングツールを探すのに手間取ってしまった。

原因は

  • リサイズツールと混同していた事
  • ツールの使い方が分からなかった事

最初に見つけたツールは、使い方が分からずじまい(何故か余計なところまで切り取ってしまう)だったし、
最後に辿り着いたPhotoShifferに関しても、パラメータの指定方法をマニュアル読むまで分からなかった。
(残す長方形を[左上](x1,y1),[右下](x2,y2)と指定するものとばかり思っていたけれど、
PhotoShifferでは、元の長方形から、上下左右(y1,y2,x1,x2)を指定する形式だった)

慣れない事をすると、意外な時間がかかってしまうのだなぁと感じた。


GIFアニメをアップしようとして、失敗。
はてなでは、150*150以下のサイズで、それぞれビットマップを保存していないと、駄目なのか。
ムムム。

MPI-レイテンシ

並列計算機規格MPIのライブラリであるLAM(version7)の通信速度が気になったので、レイテンシを計測してみた。
メッセージの送受信を役割を交互に変えて、10^5回送受信を繰り返すプログラムを用いた。
経過時間とCPU利用時間を測定した。

結果は下図のようになった。


同一PC内の2CPU間では、LANケーブルを介した通信を行っていないので、 
処理が早く、CPUのほとんどをMPIのプロセスが占めている事がわかる。

異なるPCの2CPU間では、通信に時間がかかるために、
待ち時間が生じていて、その間は他のプロセスを行っている事が分かる。
普通、アルゴリズムの性能評価の指標にはCPU利用時間を用いるのだけども、
並列計算では通信の為に経過時間を指標にする必要性を確認できた。

レイテンシが他の測定結果(MPIライブラリの調査と性能の計測)よりも、
倍以上遅くなってしまっているのも気になるけれど、改善策が思い浮かばない。


測定に用いたプログラムはこちら。実行にはlamの環境が必要。

latencyMeasure.cpp

#include "mpiInterface.h"
#include "timeUtility.h"
#include <mpicxx.h>
#include <stdio.h>

int main(int argc, char** argv)
{
	
	int repeat = 100000;

	MPI::Init(argc, argv);
	
	int my_rank =  MPI::COMM_WORLD.Get_rank() ;
	
	mpiInterface inter = mpiInterface();
	
 	timeUtility time = timeUtility();
 
	for(int i=0;i<repeat * 2;i++){
		if((i + my_rank) % 2 ==0) inter.send();
		else inter.recv();
	}
	
	if(my_rank ==0){
		time.showTime();
		time.showLatency(repeat);
	}
	
	MPI::Finalize();
}

mpiInterface.cpp

#include "mpiInterface.h"
#include <mpicxx.h>
#include <iostream> 

mpiInterface::mpiInterface(){

	int my_rank = MPI::COMM_WORLD.Get_rank();

	int p = MPI::COMM_WORLD.Get_size();

	if(p!=2) cout << "error" << endl;

	int targetRank;
	if(my_rank ==0) targetRank =1;
	else targetRank = 0;
	char  sendBuf[] = "Hello";
	char recvBuf[]   = "        ";
	sendRequest =  MPI::COMM_WORLD.Send_init(sendBuf,8,MPI_CHAR,targetRank,0);
	recvRequest  = MPI::COMM_WORLD.Recv_init(recvBuf,8,MPI_CHAR,targetRank,0);

}

void mpiInterface::send(){
	sendRequest.Start();	
	sendRequest.Wait();	
}
	
void  mpiInterface::recv(){
	recvRequest.Start();
	recvRequest.Wait();
}

mpiInterface.h

#ifndef _mpiInterface_h_
#define _mpiInterface_h_

#include <mpicxx.h>

class mpiInterface{
private:
	MPI::Prequest sendRequest;
	MPI::Prequest recvRequest;
public:
	mpiInterface();
	void send();
	void recv();
};
	
#endif

timeUtility.cpp

#include "timeUtility.h"
#include <stdio.h>
#include <fstream> 
#include <sys/time.h>

timeUtility::timeUtility(){
	stime_clock  =clock();
	stime_gettimeofday = gettimeofday_sec();
}

double timeUtility::gettimeofday_sec(){
	struct timeval tv;
	gettimeofday(&tv,NULL);
	return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

void timeUtility::showTime(){
	cout <<  "Passing time is " <<   (double) (gettimeofday_sec() - stime_gettimeofday) <<endl;
	cout <<  "CPU using time is " <<  (double) (clock() - stime_clock )/CLOCKS_PER_SEC << endl;
}

void timeUtility::showLatency(int repeat){
	cout <<  "Latency(Passing time ) is " << (double) (gettimeofday_sec() - stime_gettimeofday) /repeat<< endl;
	cout <<  "Latency(CPU using time ) is " << (double) (clock() - stime_clock )/CLOCKS_PER_SEC /repeat << endl;
}

timeUtility.h

#ifndef _timeUtility_h_
#define _timeUtility_h_

#include <time.h>

class timeUtility{
private:
	clock_t stime_clock; 
	double stime_gettimeofday;
public:
	timeUtility();
	double gettimeofday_sec();
	void showTime();
	void showLatency(int);
};

#endif

書いてから思ったけども、doxygen使ったページを上げれば、良かったかな・・・

物質になぜ重さある? 

物質に重さがあるのは当たり前だと思っていて、私の解釈だと、
その理由は、互いに引き付けあう力があって、地球にひきつけられる(重力)が存在するから。
だけども、なんで引き付けあう力があるかって、実は分からない。

更にいえば、上の解釈は重さの説明に近いけれども、質量の説明には全くなっていない。
(重さは測定系に依存するのに対して、質量は物質固有の値)

その辺のブラックボックスを解き明かそうとする研究がニュースになっていた。
http://www.asahi.com/science/update/0424/TKY200704240344.html

神の存在証明

ゲーデルの神の存在証明に関する記事を読んだので、考察してみる。
ほとんど言葉遊びだと思う。

簡単な紹介はこうなっている。

God, by definition, is that than which a greater cannot be thought.
God exists in the understanding.
If God exists in the understanding, we could imagine Him to be greater by existing in reality.
Therefore, God must exist.


都合の良いように意訳してみる。
・定義により、神より偉大なものはない。・・①
・神は空想の中にはいるとする。・・②
・もし空想の中に神がいるなら、私たちは彼より、偉大な彼を空想できる。・・③
・すなわち神は現実にいる。・・④


①②③から④までを「すなわち」で繋げられるほど賢くないので、①②③から少しづつ④に近づけようとしてみる。


②の仮定のもとで③を解釈すると、私たちは彼(神)より偉大な彼を空想できる。
となって、①と矛盾する(ってゲーデルは考えたのだろう)。 
背理法的に考えると、②がおかしいことがわかる。
つまり、「神は空想の中にはいない」・・⑤が示される。


とはいえ、⑤から④には飛躍があるので、新しい条件を追加する。
・神は空想の中か、現実にいる・・⑥
条件⑥を追加したのは、
・神という概念が生まれたのは、誰かが思いついたか、実際にいたかのどちらかに違いない・・⑦
という納得できないこともない条件⑦から。


⑤⑥を使えば、神は現実にいる・・④が示せた。



反論するポイントを2点思いついた。


1点は①②③から⑤への導入が
「無限より大きい数は存在しないから、無限は存在しない。」
の議論と同質である点。
2点は条件①と条件⑦を同時に考えると、納得しづらい点。

doxygen

今更ながら、卒論で作ったC++プログラムをdoxygenでドキュメント化した。

doxygenのインストールはここから。
メインプログラムに@mainpageを書いて、指示通りにやれば、構造解析してくれる。

卒論でメインに使ったプログラムは公開するわけにいかないので、
MPIの勉強用に作ったライフゲームのdocをサンプルとして置いておく。