2008年11月10日月曜日

OpenMP 入門 #4

林檎生活100: OpenMP 入門 #3の続き.今回は,sections ディレクティブについて.

sections ディレクティブは,かなり単純.A という処理と B という処理があって,それぞれ独立しているときには両方同時にやっちゃっていいよねってことだ.

使い方は,次のようなかんじになる.

#include <omp.h>

#define N 1000

int main(void)
{
int i;
float a[N];
float b[N];
float c[N];
float d[N];

for (i = 0; i < N; i++) {
a[i] = i * 1.5;
b[i] = i + 22.35;
}

#pragma omp parallel shared(a, b, c, d) private(i)
{
#pragma omp sections nowait
{
#pragma omp section
for (i = 0; i < N; i++)
c[i] = a[i] + b[i];
#pragma omp section
for (i = 0; i < N; i++)
d[i] = a[i] * b[i];
}
}

return 0;
}


結構便利そうだが,この場合は当然セクションの計算量の多いほうに足を引っ張られるので,計算量のバランスは重要だと思う.まあ,セクションの数(今回は2つだが,独立なセクションがあれば3つでも4つでも OK.)を増やせば,あるていど均されるんだろうけど.

参考文献:
OpenMP Tutorial

2008年11月6日木曜日

MD5, SHA-1 チェックサムの確認方法

Mac OS X で,チェックサム(ハッシュ,ダイジェストとかっても呼ばれるね.)を確認する方法.たぶん,あんまり使う機会がないとは思うんだけどねw僕は,MacPorts で無理矢理インストールするために,チェックサムをいじった記憶がある.(本当は,よくないんだけどさw)

MD5 は,直感的なコマンドで OK なんだよねw
$ md5 ファイル名

SHA-1 が問題.実は,openssl というプログラムを使って,こんな風にやる.(たぶん,どの環境でもインストールされてるはず.じゃないと,ほかのソフトウェアが困るはずだから.)
$ openssl sha1 ファイル名

ちなみに,openssl でほかの規格のチェックサムも調べられる.(man openssl からの抜粋なので,詳しくは,そっちを読んでね.)
       md2       MD2 Digest
md5 MD5 Digest
mdc2 MDC2 Digest
rmd160 RMD-160 Digest
sha SHA Digest
sha1 SHA-1 Digest
sha224 SHA-224 Digest
sha256 SHA-256 Digest
sha384 SHA-384 Digest
sha512 SHA-512 Digest

base64 とかのエンコード系も調べられるみたい.DES などの暗号系も.すげぇなwちなみに,Mac OS X としての正しい使用方法は,参考文献のページに書いてるので,そっちを参考にしてね♪

参考文献:
Mac OS X: SHA-1 ダイジェストを確認する方法

2008年11月2日日曜日

iCal に祝日を追加する

最近は,iCal を使うようになった.ふと考えてみると,iCal には祝日が表示されないのだ.うーん,だれかこの情報を追加するプログラムとか作ってないかなぁとか思ったら,Apple がちゃんと準備してくれてたw

Apple のカレンダーライブラリに行って,祝祭日の中の日本をクリックするだけだね.めんどくさい人は,次のリンクをクリックすれば,iCal が自動的に開いて追加できる.

webcal://ical.mac.com/ical/Japanese32Holidays.ics

僕は,一応自動更新を「毎日」に,色を休みの日らしく「レッド」に設定したよ♪

2008年10月29日水曜日

C 言語の話#2 char *const c; って何?

C 言語について,ふと思ったことや,調べてみたことなどを書くことにした.

今回は,const について.一般的な C 言語入門書で解説される const の使い方ってこんなんだった気がする.

float circle(float r) {
const float pi = 3.14159265;

return r * r * pi;
}


この場合は,円周率 pi が定数ですよってことを示すために,const を付けていることになる.メリットは,プログラマが勘違いして関数中で代入する間違いが避けられるとかいう話になるのかな.あとは,コンパイラによって最適化されやすくなる.(まあ,いまのコンパイラは賢いから,この情報が無くても最適化してくれると思うけど.)

現実的には,const は次のように使われていると思う.(Book は typedef 宣言で宣言された本の構造体への型ってことで.構造体のような大きなサイズの変数を値渡しすると,そのコピーに時間がかかるので,アドレス渡しが基本になるからね.)

int get_isbn(const Book *book) {
return book->isbn;
}


これは,Book 型の変数へのポインタを渡しても,内部でその値が書き換えられることはありませんよってことを示している.つまり,次のような処理は許されないんだよね.

int get_isbn(const Book *book) {
book->isbn = 1234567890; // コンパイルエラー

return book->isbn;
}


これの何がおいしいかというと,ひとつは開発者側のミスが無くなることなんだ.仕様上引数の値を変更する必要が無いとわかっているのであれば,インターフェースにあたる仮引数に const を付けることによって,関数の実装で間違って代入してしまうようなことが避けられる.もうひとつは,これが公開関数だった場合,ユーザ側が安心して関数を使えること.この関数にアドレス渡ししても,その値が更新されることが無いことが保証されているからね.

最後に,タイトルにあげた質問の答え.前述の Book で考えると次のようになる.

int get_isbn(Book *const book) {
book->isbn = 1234567890; // コンパイルエラーにならない
book = NULL; // コンパイルエラー

return book->isbn;
}


つまり,book の示すアドレスの変更を不可能にするのだ.(だから,const Book *book の場合は,book = NULL; はコンパイルエラーにならない.)ちょっと見慣れないかんじだと思うので,しっくり来ないかもしれない.タイトルにまでしていてあれだけど,ほとんど使う機会はないので無視してしまっていいと思う.(僕としてはそういう認識.いや,使う機会がすごくあるという人は,コメントに書いていただけると助かる.)

もちろん,こういう書き方もある.まあ,僕は使うこと無いけど.
int get_isbn(const Book *const book) {
book->isbn = 1234567890; // コンパイルエラー
book = NULL; // コンパイルエラー

return book->isbn;
}


ということだね.参考になったかなぁ.

参考文献:
平林雅英.新ANSI C言語辞典,技術評論社,1997.

2008年10月28日火曜日

C言語の話#1 仮引数での配列添字演算子はシンタックスシュガー

久しぶりの更新で,C言語の話.最近までちゃんと知らなかったので,備忘録的にエントリにしてみた.

配列を引数にとる関数の定義は,次のようなかんじになると思う.
void f(int a[])
{
/* 処理 */
}

また,次のようにかいても問題ない.
void f(int *a)
{
/* 処理 */
}

というか,前者は後者のシンタックスシュガーでしかない.
int a[8];
a = NULL;

は,コンパイルエラーになるが,
void f(int a[]) {
a = NULL;
}

は,コンパイルエラーにならないことから理解できる.

となると,次のような2次元配列の場合が気になる.
void f(int a[][8])
{
/* 処理 */
}

これは,次の記述と同じ意味になる.
void f(int (*a)[8])
{
/* 処理 */
}

予想と違ったという人も結構いると思う.int *a[8]ではなくint (*a)[8]なのだ.ちなみに,前者は,int型へのポインタの配列で,後者は,int型の配列へのポインタだ.

さて,なんでこんなことになってんだろう.これについては,次のプログラムを見てほしい.
int a[8];
f(a);

何ら変哲のない,配列を関数に渡すプログラムだ.しかし,このとき関数に渡されるのは,本当に配列だろうか?実は,アドレスでしかない.配列として確保された領域の先頭アドレスだ.(知っていると思うけど,aと&a[0]が同じ.)つまり,配列を渡しているというわけではないのだ.

そう考えると,次のような2次元配列のときの説明も容易だ.
int a[4][8];
f(a);

渡しているのは,2次元配列の先頭アドレスである.(aとa[0]と&a[0][0]が同じ.)しかし,2次元配列であるので,列の要素数を知らなければ,2次元配列としてアクセスができないのだ.(列の要素数がわからないと,次の行がどの番地から始まるのか計算できない.)もちろん,2次元以上の多次元配列にも同様のことがいえる.

ということで,こんな風にまとめたわけだけど,間違ってそうで怖いなwC言語に超詳しい人ってざらにいるしw間違ってたら教えてください(*- -)(*_ _)ペコリ

参考文献:
B.W.カーニハン,D.M.リッチー.プログラミング言語C 第2版, 共立出版, 1989.
平林雅英.新ANSI C言語辞典,技術評論社,1997.

2008年10月26日日曜日

LaTeX に UTF-8 な TeX ファイルを食わせる方法

エンコーディングを UTF-8 にした TeX ファイルをコンパイルすると文字化けしてしまう.その解決策.

$ platex --kanji=utf8 sample.tex


というふうに,kanji オプションをつけるだけ.MacPorts からインストールした LaTeX はこれでいけた♪

2008年10月2日木曜日

iPod shuffle 買った♪

iPod shuffle を買った♪カラーは,(PRODUCT) RED♪いい.かさばらないし,かっこいいし,ほんと快適♪

唯一かさばったケーブルは,こんなふうに編んでみたw




そういや,ケーブルの材質変わった?iPhone のときも思ったんだよな.新しいからかなぁ.iPod 5G のケーブルみたいに自然に垂れ下がらない.

参考文献:
iPod情報局: 三つ編みヘッドホンコードで絡まりを追放
テド★えにっき +とらちっく: 編み編みshuffleさん