limitusus’s diary

主に技術のことを書きます

iccをインストールした記録

Intel C コンパイラって買わないと使えないのかと思ってたけど、非商用ならば無料でインストールできることがわかったので実際にやってみた。

ダウンロードまで

これは 2011 年 11 月 18 日の操作記録だが、サイト更新に伴いページ構成が変更されたりリンクが切れる可能性がある。

C Compiler & C++ Compiler Suite from Intel - Intel® Software Network

この辺に IntelC/C++ 系開発用ソフトウェアがまとめられていた。
画面上部の Tools & Downloads から Free Non-Commercial というのを選ぶ。

Non-Commercial Software Development - Intel® Software Network

ここで非商用利用の規約に同意する。

その後いくつかのソフトウェアを選択できる。ここでは Intel® C++ Composer XE 2011 for Linux を選択した。
あとは必要事項を入力すればダウンロードできるようになる。

ライセンス番号もさりげなく画面に表示されるので忘れずに控えておく。

インストー

tarball を落としてきたので、適当に展開し、その中の ./install.sh を実行する。
あとは画面の指示に従ってライセンス番号やインストール先を指定していけばいい。
root 権限があればシステム領域にインストールできるし、今回はユーザ領域($HOME/intel 以下)にインストールした。
RPM 系のディストリビューションではなかった & tarball の中には rpm ファイルもあったが、特に問題なくインストールできた。

lookupDictionary.js を直してみた

とっても便利な Vimperator プラグインの lookupDictionary.js。
どうやら ALC 側で XPath が変更されてしまったらしく結果が帰ってこなくなってしまったため、簡単に修正。

Index: lookupDictionary.js
===================================================================
--- lookupDictionary.js	(リビジョン 37220)
+++ lookupDictionary.js	(作業コピー)
@@ -13,7 +13,7 @@
     names: ['eiji[ro]'],
     url: 'http://eow.alc.co.jp/%s/UTF-8/',
     shortHelp: 'SPACE ALC (\u82F1\u8F9E\u6717 on the Web)',
-    xpath: 'id("resultList")',
+    xpath: 'id("resultsList")',
     dictionary: 'en-US'
 },{
     names: ['goo[dictionary]'],

快適な辞書ライフを!

Python で signal と threading を両立してみた

経緯

最近書いているプログラムで無限ループするワーカースレッドを立てまくるものがあって, それを signal で安全に終了させる手段が知りたかった.

課題プログラム

以下のようなプログラムがあります.

import threading
import time
def loopfunc(event):
    print "Thread Started"
    while not event.isSet():
       time.sleep(1)
    print "Thread End"

def main() :
    threads = []
    e = threading.Event()
    for x in range(10):
        threads.append(threading.Thread(target=loopfunc, args=(e,)))
        threads[x].start()
    for th in threads:
        th.join()

main()

これを起動すると10個のスレッドが作られて, 無限ループします. これに対して SIGINT などを送っても何も起きません. これは Python の thread 全体に対していえることらしいです. たとえば明示的にシグナルハンドラを作って

import threading
import time
import signal
def loopfunc(event):
    print "Thread Started"
    while not event.isSet():
       time.sleep(1)
    print "Thread End"

def sighandler(event, signr, handler):
    event.set()

def main() :
    threads = []
    e = threading.Event()
    signal.signal(signal.SIGINT, (lambda a, b: sighandler(e, a, b)))
    for x in range(10):
        threads.append(threading.Thread(target=loopfunc, args=(e,)))
        threads[x].start()
    for th in threads:
        th.join()

main()

としても, やはり SIGINT は無視されます. これはなぜかというと, join() を呼んでいる最中は signal を受け付けないからです.

解決策

これは絶対に誰か出会った問題だろうと思って調べてみたら(下の参考ページ参照), 開始直後に os.fork() してシグナルハンドラを登録し, スレッドのマスターに SIGKILL を送信することによって解決するという方法が掲載されていました. しかしさすがにこれは乱暴すぎるような気がしたので, もう少し穏やかな終了方法を考えてみました. ふと見るとこれ, 先輩のページだ!

import threading
import time
import signal
def loopfunc(event):
    print "Thread Started"
    while not event.isSet():
       time.sleep(1)
    print "Thread End"

def sighandler(event, signr, handler):
    event.set()

def main() :
    threads = []
    e = threading.Event()
    signal.signal(signal.SIGINT, (lambda a, b: sighandler(e, a, b)))
    for x in range(10):
        threads.append(threading.Thread(target=loopfunc, args=(e,)))
        threads[x].start()
    for th in threads:
        while th.isAlive():
            time.sleep(0.5)
        th.join()

main()

このように 0.5 秒に1回, スレッドの生存を確認することによって join() を呼ばず, シグナルを受け付けられるようにしてみました. この他にも join([timeout]) に引数を渡して isAlive() で調べるループにするという方法もアリだと思います.

これがベストなのかどうかは分かりませんが, やりたいことは実現できたのでメモ.

Embarrassingly Parallel なプログラムを pthread で並列化してみた

やったこと

後輩の授業で Embarrassingly Parallel なプログラムを並列化するという課題が出ていたので、ちょっとやってみました。

実際に使ったコードはgithubで公開中です。公開は課題の締切後に行いました。

課題1 1次元関数の数値積分区間分割による並列化

実関数 $f(x)=sin(x)$ が与えられ、$\int_0^{\pi/2} f(x) dx$ を区分求積法で求めるプログラムがあったとき、区間 $(0, \frac{\pi}{2})$ を N 分割し、 N 個の POSIX thread に割り当てて並列化するという問題です。

この課題は練習用で、プログラムは公開されていました。単に走らせて性能を測ればよいものでした。

課題2.1 素数探索プログラムの区間分割による並列化

2から10000000までの整数のうち、素数がいくつあるかを数えるプログラムが与えられたとき、区間を N 個に分割し、 N 個の POSIX thread で並列化する問題です。課題1のコードを利用すればできる比較的簡単な課題です。

課題2.2 素数探索プログラムの負荷分散を考慮した並列化

素数の分布は一様ではないため、課題2.1のコードでは負荷が偏ってしまいます。そこで区間を M 分割し、 N 個の POSIX thread を利用することで並列化するのが本課題です。

やりかたは単純で、

  1. 区間を M 個に分割し、それぞれをタスクとして作る。
  2. N 個の POSIX thread を作る。

というものです。各 thread は

for j in range(0 .. M-1) :
  if (j 番目のタスクは終わっていない) :
    j 番目のタスクをやる

とふるまいます。これに排他制御を行います。タスクを表す構造体に「手を付けた」というフラグを追加します。

for j in range(0 .. M-1) :
  lock(mutex)
  if (j 番目のタスクは誰も手を付けていない) :
    j 番目のタスクに手を付ける
    unlock(mutex)
    j 番目のタスクをやる
  else :
    unlock(mutex)

このようにすれば OK です。

続きを読む

「事業仕分けに対する緊急声明」を聞いてきた

大学にいる人間として(, そして一利害関係者として), ちょっと真面目に生意気なことを書いてみます.

何があったのか

大学でノーベル賞・フィールズ賞受賞者による事業仕分けに対する緊急声明と 科学技術予算をめぐる緊急討論会 - お知らせ - 東京大学 大学院理学系研究科・理学部というイベントがあったので, 行ってみました. 私の立場はせいぜい研究室に所属する学部学生であって, 研究室の先生が予算を取ってくれていて, そのお金によって研究室の運営ができている, その恩恵にあずかっている存在です. そんな学部学生ですが, 基礎研究(Science)および科学技術(Science-based Technology)に関する予算が削減されることが「ヤバい」ことくらいは直感で分かっているつもりです. 私の周囲には研究者, 技術者の方が多いので眺めてみても, この直感は外れていなかったと思っています. その中で, ノーベル賞, フィールズ賞を受賞なさった教授陣が声明を発表したわけです.

前日(11月24日)には国立大学の学長クラス*1が記者会見を開いていて(記者会見「学術・大学関連予算について」の開催 【共同声明】大学の研究力と学術の未来を憂う −国力基盤衰退の轍を踏まないために−), これが開かれただけでも「相当な異常事態だな」とは思っていたのですが, これに加えて更に開かれたわけで, これは深刻な状態だと感じました.

どうやら反応として「ノーベル賞を受賞した学者を出すのは思考停止だ」とか, 「金融を軽視してる」とかいう意見が存在しているようですが, 前者はそれなりに狙った部分もあるようです. しかし, 研究というのは百発百中ではないし, 投げてみるまでどれが当たるのか分からない性質があり, その中である意味で「たまたま当たった」人がノーベル賞受賞者なわけです. その「当たる/当たらない*2」の線を体感している方々が声明を出すというのは, 大きな意味があると思います. 次に後者ですが, 「声明文では科学技術創造立国が目標であるとなっているが, 我が国に金融分野での発展はないのか」という質問に対する, 「金融は知は産まない. 財は産むけど」という返答に反応した意見だと思います. しかし経済学と区別された金融は知を産んでいるかというと, 果たしてそうなのか?という疑問が(少なくとも私には)あります. また, 東大には元々金融に関する研究機関はなかったはずで, 2005年に初めて金融システム専攻ができ, 2年前から経済学部の中で経済学科/金融学科が分かれるようになった程度だと認識しています. そういう意味で東大としては「金融分野は学術領域として成熟しておらず, 研究実績がない」という立場だったのかな, と思っています. 会場では質問そのものが「『理系内閣』と言われた内閣のはずなのに科学技術の予算が削られる」ことを問題視している議論の最中に金融の話がピンボケだと感じられ, そこにうまい返しが入ったことから拍手が起きた, ということだと思います. それは金融を軽視しているとかバカにしているとかではなく, 「対象とする領域が全然違う」ということでしょう. とはいえ, あの部分だけ聞けばそう思うのももっともな話なので, 配慮すべきだったと思いますが…

討論会としては, 壇上で喋りすぎて質問の機会が少なすぎたのでは?と感じました. また, 会場が狭すぎて入りきれていなかったので, もう少し広い会場が用意できたらよかったのかな, と感じました.

声明

以下のページに声明文の全文が掲載されています.

横山広美のお知らせページ : 声明文

重要なことしか書かれていない*3ので全部重要なのですが, 予算が途切れる→その間研究者がいなくなる→科学/技術が低迷→予算を付ける→学ぼうとする人ができても, それを教えられる人が不足する, という状況が起きて, それは取り返しがつかない. 現在の「事業仕分け」と称した作業はそれを引き起こしかけてるよ, ということです. 私はこれは至極もっともなことだと考え, 署名してきました.

署名

会場にいらっしゃらなかった方でも, 現在 Web 上から署名を行うことができます. 声明に賛同できる方はどうぞ.

署名簿: ノーベル賞・フィールズ賞受賞者による事業仕分けに対する緊急声明

*1:慶應義塾大学は「慶應義塾長」と呼ぶため

*2:外れたって言い方は適切じゃないですよね

*3:不要なものは排除してあります!

Goをビルドしてみた

Google が Go という言語処理系をリリースしたので、さっそくビルドしてみました。

環境

手順

環境変数の設定

Go では環境変数をいくつか設定しておく必要があります。これはその場で設定するのではなく、~/.bashrc などに書いておく必要があるようです。
また、$GOBIN を設定したところには予め $PATH に追加しておく必要があります。

hg clone

公式ページの手順通りに hg clone します。

% env | grep GO
GOBIN=/home/limit/local/go
GOARCH=amd64
GOROOT=/home/limit/hg/go
GOOS=linux
$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT
処理系のビルド

普段 NIS を使っている環境でビルドしたので、さまざまな問題を避けるため

  1. 最初は bash でログインする
  2. .bashrc の中で zsh があることを確かめ、zsh を起動する

という処理を行っています。こういう変な設定をしていると環境変数がうまく処理できないらしく、単に src で ./all.bash を叩いても動きませんでした。

仕方がないので all.bash の中を見て、ある程度手作業でやってみることにしました。
all.bash は make.bash と run.bash を起動しているだけです。

make.bash の先頭では $GOROOT が正しく設定されているかどうかをチェックしていて、これが上記の原因でうまく通っていませんでした。したがってそこを飛ばして、ビルドを行いました。このスクリプトの中で $GOBIN/quietgcc というスクリプトを生成していて、これを使っているため、 $GOBIN には $PATH が通っていないとダメです。

2009/11/12追記:これはこちらの勘違いだったようで、環境変数を正しく設定していたら上記の処理をした環境でも問題なく動作してくれました。

テスト

テストは run.bash で行われます。これは環境変数を気にせず、そのまま走らせました。
どうやら net のテスト付近で失敗したようです。
2009/11/12追記:このエラーは解消されました(エラーメッセージは下へ移動しました)。詳細は下記。

さしあたり、 src/pkg/Makefile の NOTEST リストに net を追加したところ他のテストはうまくいきました。

多分これのバグレポートを投げたりしないといけないですねー。
2009/11/12追記:投げました! net: TestDialError fails · Issue #32 · golang/go · GitHub
2009/11/12さらに追記:別の問題にMergeされていて、エラーメッセージが異なるから新たなIssueとして登録したはずなのに何かと思ったらこの net というテスト自体がテスト対象から外されたようです。これでエラーは出ません。net: TestDialError fails · Issue #23 · golang/go · GitHub

Python 的簡単さと C, C++ 的性能を持ち合わせるということなので期待です。

続きを読む