<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
 xmlns:image="http://pirl.org/rss/1.0/modules/image/"
 xmlns:admin="http://webns.net/mvcb/"
>
<channel rdf:about="http://dsas.blog.klab.org/">
<title>DSAS開発者の部屋</title>
<link>http://dsas.blog.klab.org/</link>
<description>
</description>
<dc:language>ja</dc:language>
<admin:generatorAgent rdf:resource="http://blog.livedoor.com/?v=2.0" />
<image rdf:resource="http://image.profile.livedoor.jp/icon/klab_gijutsu2_60.gif"/>
<items>
 <rdf:Seq>
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51434186.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51423317.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51395944.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51393628.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51390187.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51389536.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51389200.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51388703.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51386297.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51385301.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51380201.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51368711.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51361402.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51353125.html" />
  <rdf:li rdf:resource="http://dsas.blog.klab.org/archives/51345077.html" />
 </rdf:Seq>
</items>
</channel>
<image rdf:about="http://image.profile.livedoor.jp/icon/klab_gijutsu2_60.gif">
 <title>DSAS開発者の部屋</title>
 <link>http://dsas.blog.klab.org/</link>
 <url>http://image.profile.livedoor.jp/icon/klab_gijutsu2_60.gif</url>
</image>
<item rdf:about="http://dsas.blog.klab.org/archives/51434186.html">
<title>Windowsプログラムの異常終了をトラップするコード</title>
<link>http://dsas.blog.klab.org/archives/51434186.html</link>
<description>■ はじめに


先日、社内でこういう話題がありました。

「Windows 上のプログラム A からソースコードのないプログラム B を起動する必要があるんだけど、プログラム B はときどき異常終了しちゃったりする。内輪用だから落ちること自体は目をつぶるとして、プログラ...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-06-24T10:59:44+09:00</dc:date>
<dc:subject>win</dc:subject>
<content:encoded><![CDATA[<b>■ はじめに</b>
<br>
<br>
先日、社内でこういう話題がありました。
<br>
「Windows 上のプログラム A からソースコードのないプログラム B を起動する必要があるんだけど、プログラム B はときどき異常終了しちゃったりする。内輪用だから落ちること自体は目をつぶるとして、プログラム B が異常終了した場合にはプログラム A 側でそれを上手にハンドルしたい。良い方法はないものか」
<br><br>
この話に興味を感じ、異常終了を起こす短いプログラムを作ってデバッガでトレースしながらヒントを探している内にふと思いました。
<br><br>
<center>
<img src="http://image.blog.livedoor.jp/klab_gijutsu2/imgs/4/b/4b029333.png">
</center>
<br>
このプログラムを裸で実行すると、プログラム内で処理されない例外は図のような形でシステムによって処理されます。しかし、デバッガ上でデバッギ（デバッグ対象）として実行している場合はデバッガが例外の発生を検知しそれをユーザに伝えます。つまり、デバッガの制御下にあります。
<br><br>
ということは「デバッガとして動作するコード」を用意しプログラム B をデバッギとして扱えば、そこで発生した未処理の例外を捕捉することができるかもしれません。

ちょっと面白そうなので試しにそういうプログラムを書いてみることにしました。
<a href="http://dsas.blog.klab.org/archives/51434186.html">続きを読む</a>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51423317.html">
<title>まくおさんバージョンアップのお知らせ(Ver1.2.0)</title>
<link>http://dsas.blog.klab.org/archives/51423317.html</link>
<description>
まくおさんをバージョンアップしましたのでお知らせします。
主な変更点は以下のとおりです。


【Ver1.1.3→Ver1.2.0】

応答速度と安定性の向上
エラーログに&quot;[error]&quot;という文字列を追加
メンバがタイムアウトしたときの状況を詳細に出力するようにした
msync ...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-05-25T21:23:07+09:00</dc:date>
<dc:subject>運用</dc:subject>
<content:encoded><![CDATA[<P>
まくおさんをバージョンアップしましたのでお知らせします。<BR>
主な変更点は以下のとおりです。
</P>
<P>
【Ver1.1.3→Ver1.2.0】
<UL>
<LI>応答速度と安定性の向上
<LI>エラーログに"[error]"という文字列を追加
<LI>メンバがタイムアウトしたときの状況を詳細に出力するようにした
<LI>msync --statusで、実行中のコマンドを表示するようにした
<LI>msyncを複数同時実行したときに挙動がおかしくなる不具合を修正
<LI>ファイルクローズに失敗したときに異常終了する不具合を修正
<LI>msyncにdeleteオプションを指定したときの結果表示がおかしくなる不具合を修正
<LI>その他細かい不具合を修正
</UL>
</P>
<P>
【ダウンロード】
<UL>
<LI><B><A HREF="http://sourceforge.net/project/showfiles.php?group_id=241125">ダウンロードページ</A></B>
<LI><B><A HREF="http://downloads.sourceforge.net/makuosan/makuosan-1.2.0.tar.gz">makuosan-1.2.0.tar.gz</A></B>
</UL>
</P>
<FONT COLOR=RED><B>
【注意】<BR>
Ver1.2系とVer1.1系はプロトコルに互換性がありませんので、<BR>
バージョンアップは全サーバに対して実施して下さい。<BR>
</B></FONT>
</P>
<P>
「ところで、まくおさんってだれ？」という方は、<A HREF="http://lab.klab.org/wiki/Makuosan">こちら</A>や<A HREF="http://dsas.blog.klab.org/archives/51342234.html">こちら</A>を見てやってください(^^;
</P>
]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51395944.html">
<title>phpを高速化する computed goto</title>
<link>http://dsas.blog.klab.org/archives/51395944.html</link>
<description>前回 インタプリタ型言語を高速化する computed goto で紹介したcomputed gotoを、「phpでも使えないの？」という声が社内であったので、 php のソースコードを見たところ、特定のビルド手順で php でも computed goto が使えることが判りました。そのビルド手法とベンチマー...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-30T16:03:46+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[<p>前回 <a class="reference" href="http://dsas.blog.klab.org/archives/51393628.html">インタプリタ型言語を高速化する computed goto</a> で紹介したcomputed gotoを、「phpでも使えないの？」という声が社内であったので、 php のソースコードを見たところ、特定のビルド手順で php でも computed goto が使えることが判りました。そのビルド手法とベンチマーク結果を紹介しておきます。</p>
<p>php の VM のソースコードは、phpソースパッケージ中の Zend/ というディレクトリの中にあります。zend_vm_で始まる幾つかのファイルのうち、 zend_vm_execute.h というファイルが命令ディスパッチが実装されているファイルで、このファイルは zend_vm_gen.php というスクリプトで生成されています。そして、 zend_vm_gen.php のオプションで、命令ディスパッチの方法を選択できます。(phpのビルドにphpが必要です)</p>
<p>computed goto を使うビルド手順は以下の通りになります。</p>
<pre class="terminal">
$ tar xzf php-5.2.x
$ cd xzf php-5.2.x/Zend
$ php zend_vm_gen.php --with-vm-kind=GOTO
$ cd ..
$ ./configure --with-zend-vm=GOTO [その他オプション]
$ make
</pre>
<p>Zend/ ディレクトリの中に bench.php というファイルがあったので、これを使って通常の関数ポインタ配列版とcomputed goto版の速度を比較してみました。</p>
<pre class="terminal">
# 関数ポインタ配列版.
$ ~/local/stow/php-5.2.9-func/bin/php bench.php
simple             0.319
simplecall         0.412
simpleucall        0.639
simpleudcall       0.693
mandel             0.991
mandel2            1.311
ackermann(7)       0.767
ary(50000)         0.047
ary2(50000)        0.037
ary3(2000)         0.534
fibo(30)           1.739
hash1(50000)       0.087
hash2(500)         0.098
heapsort(20000)    0.312
matrix(20)         0.257
nestedloop(12)     0.539
sieve(30)          0.232
strcat(200000)     0.034
------------------------
Total              9.047

# computed goto版
$ ~/local/stow/php-5.2.9-goto/bin/php bench.php
simple             0.283
simplecall         0.360
simpleucall        0.584
simpleudcall       0.645
mandel             1.022
mandel2            1.213
ackermann(7)       0.788
ary(50000)         0.046
ary2(50000)        0.036
ary3(2000)         0.485
fibo(30)           1.716
hash1(50000)       0.079
hash2(500)         0.090
heapsort(20000)    0.276
matrix(20)         0.237
nestedloop(12)     0.479
sieve(30)          0.234
strcat(200000)     0.035
------------------------
Total              8.610
</pre>
<p>5%くらい速くなっていますね。
Python 3.1 だけじゃなくて php をビルドするときも computed goto を試してみて下さい。</p>

<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51393628.html">
<title>インタプリタ型言語を高速化する computed goto</title>
<link>http://dsas.blog.klab.org/archives/51393628.html</link>
<description>先日Python 3.1a1 がリリースされました。 Python 3.0 は Python 2.6 に比べてパフォーマンスが悪かったのですが、Python3.1はPython2.6よりも速くなるかもしれません。
Python3.1のパフォーマンス向上は、主に次の2点が影響しています。

ioモジュールがC言語で書き直さ...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-23T16:04:37+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[<p>先日Python 3.1a1 がリリースされました。 Python 3.0 は Python 2.6 に比べてパフォーマンスが悪かったのですが、Python3.1はPython2.6よりも速くなるかもしれません。</p>
<p>Python3.1のパフォーマンス向上は、主に次の2点が影響しています。</p>
<ul>
<li>ioモジュールがC言語で書き直された</li>
<li>computed goto の採用 (--with-computed-gotos というconfigureオプションで有効)</li>
</ul>
<p>computed goto という名前を聞き慣れなかったのですが、調べてみると  Ruby 1.9 の VM (YARV) や、 Perl6 の VM として開発されとうとうリリースされた Parrot にも採用されている手法でした。今回は簡単に computed goto の紹介をしてみます。</p>
<div class="section">
<h3><a id="label-as-value" name="label-as-value">とりあえず label as value</a></h3>
<p>C言語の規格で規定されているgoto文は、ラベルに対して無条件ジャンプする構文です。このようにして使います。</p>
<pre class="prog">
    goto label;
    puts(&quot;foo&quot;); // 表示されない.
label: //ここにジャンプする.
    puts(&quot;bar&quot;);
</pre>
<p>ラベルはシンボル（名前）であって値ではないのですが、ラベルのアドレスを取得する <a class="reference" href="http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html">label as value</a> という拡張機能がgccにあります。</p>
<p>label as value を使うと、上記のコードは次のように書くことが出来ます。</p>
<pre class="prog">
    void *jump_target = &amp;&amp;label;
    goto *jump_target;
    puts(&quot;foo&quot;);
label:
    puts(&quot;bar&quot;);
</pre>
<p>ジャンプ先アドレスを変数に格納できるのがキモになっています。</p>
</div>
<div class="section">
<h3><a id="computed-goto-switch" name="computed-goto-switch">computed goto を使ってswitch文を高速化</a></h3>
<p>インタプリタ型言語では大抵、次のようなバイトコードに対応した処理を実行する部分(命令ディスパッチ)が実行時間の大半を占めます。</p>
<pre class="prog">
for (;;) {
    code = *code_pc++;
    switch (code) {
    case CODE_ADD:
        // 足し算処理.
        break;
    case CODE_SUB:
        // 引き算処理.
        break;
    // ...
    case CODE_END:
        goto LOOP_END;
    }
}
LOOP_END;
</pre>
<p>上記の実装では、バイトコードを1命令処理するのに次の2つの分岐を実行しなければなりません。</p>
<ul>
<li>switch-case による処理の振り分け</li>
<li>処理後にループ先頭に戻る</li>
</ul>
<p>label as value があれば、switch文をジャンプテーブルへのgotoで置き換える事ができます。</p>
<pre class="prog">
    static const void *JUMPTABLE[] = {&amp;&amp;CODE_ADD, &amp;&amp;CODE_SUB, ... , &amp;&amp;CODE_END};

    code = *code_pc++;
    goto *JUMPTABLE[code];

CODE_ADD:
    //足し算処理.
    code = *code_pc++;
    goto *JUMPTABLE[code];

CODE_SUB:
    // 引き算処理
    code = *code_pc++;
    goto *JUMPTABLE[code];
    ...
CODE_END:
</pre>
<p>これで、バイトコード一命令当たりのジャンプをひとつに減らす事ができました。このように、ジャンプテーブルを作って無条件ジャンプすることを computed goto というそうです。</p>
<p>この辺については、YARV開発者の笹田さんが <a href="http://jp.rubyist.net/magazine/?0008-YarvManiacs">YARV Maniacs 【第 3 回】 命令ディスパッチの高速化</a> という記事で詳しく説明されています。 </p>
</div>
<div class="section">
    <h3><a id="id2" name="id2">どれくらい効果があるのか</a></h3>
    <p>Python 3.1a1 がリリースされるときに、 Python-dev ML に pybench で計測したベンチマーク結果が投稿されていました。</p>
    <p><a class="reference" href="http://mail.python.org/pipermail/python-dev/attachments/20090308/3b6f20ff/attachment.txt">http://mail.python.org/pipermail/python-dev/attachments/20090308/3b6f20ff/attachment.txt</a></p>
    <p>だいたい3割前後高速になるそうです。ただし、これはベンチマーク上の話であって、実際に利用される時にはインタプリタの速度が全体の実行時間に占める比重が下がるので、そこまで効果は無いそうです。 (同じスレッド上で、Djangoのテンプレートだと7-8%ほど速度が上がったという報告がありました)</p>
</div>
<div class="section">
    <h3><a id="id3" name="id3">まとめ</a></h3>
    <p>Python3.1をビルドするときには、忘れずに --with-computed-gotos を付けましょう！</p>
</div>

<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51390187.html">
<title>IPythonでunicodeリテラルを使う</title>
<link>http://dsas.blog.klab.org/archives/51390187.html</link>
<description>
IPythonとは
IPythonとは、Pythonistaの中で絶大な人気を誇るインタラクティブシェルです。
Pythonはもともとインタラクティブシェルを内蔵しているのですが、
IPythonには内蔵のインタラクティブシェルと比べて多くの利点があります。いくつか挙げてみます。

動的補...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-13T16:22:08+09:00</dc:date>
<dc:subject>Python</dc:subject>
<content:encoded><![CDATA[<div class="section">
<h3><a id="ipython" name="ipython">IPythonとは</a></h3>
<p>IPythonとは、Pythonistaの中で絶大な人気を誇るインタラクティブシェルです。</p>
<p>Pythonはもともとインタラクティブシェルを内蔵しているのですが、
IPythonには内蔵のインタラクティブシェルと比べて多くの利点があります。いくつか挙げてみます。</p>
<ul>
<li><p class="first">動的補完</p>
<p>変数名などを途中まで入力した状態でTABキーを押すと、残りを補完してくれます。
候補が複数ある時は候補一覧を表示してくれます。</p>
</li>
<li><p class="first">シンタックスハイライト</p>
<p>プロンプトなどに色がつきます。ちょっとうれしいです。</p>
</li>
<li><p class="first">通常のシェルとしても利用可能</p>
<p>IPythonの中で、lsでファイル一覧を見たり、cdでカレントディレクトリを移動したりできます。
!vim のようにエクスクラメーションマークに続いてコマンド名を入力することで、コマンドの実行もできます。
さらに、コマンドの出力がPythonの変数に格納され、Pythonから利用可能になります。Unixの大量のコマンドを使いこなせなかったり、Windowsでコマンドが少ないことが不満だったりするときに重宝します。</p>
</li>
<li><p class="first">よく使う機能を省略形で記述可能</p>
<p>help(o) の代わりに o? でそのオブジェクトのドキュメントが読めます。</p>
<p>func(a, b) の代わりに func a b で関数呼び出しが可能です。</p>
</li>
<li><p class="first">エディタと連携可能</p>
<p><code>ed foo.py</code> のようにすることで、 <code>foo.py</code> を外部エディタで開いて編集できます。
そしてエディタを閉じると、自動的にそのファイルがevalされます。
この機能を使うと、エディタで関数を書く→IPython上で動作を確認する→エディタで関数を修正する、というサイクルでサクサク開発できます。
これに馴れてしまうと、IDEが欲しいと思わなくなります。</p>
</li>
</ul>
</div>
<div class="section">
<h3><a id="id1" name="id1">IPythonでUnicodeリテラルを使う</a></h3>
<p>IPython 0.9.1 でUnicodeリテラルを使おうとすると、次のような問題がありました</p>
<pre class="prog">
$ python
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; u&quot;あ&quot;
u'\u3042'
&gt;&gt;&gt;
$ ipython
Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
Type &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -&gt; Introduction and overview of IPython's features.
%quickref -&gt; Quick reference.
help      -&gt; Python's own help system.
object?   -&gt; Details about 'object'. ?object also works, ?? prints more.

In [1]: u&quot;あ&quot;
Out[1]: u'\xe3\x81\x82'
</pre>
<p>コンソールはUTF-8なので&quot;あ&quot; は3byteになっているのですが、それぞれのbyteを一文字と認識してUnicode文字に変換されています。</p>
<p>この問題を追ってみたところ、IPythonがPythonの組み込み関数 <code>compile()</code> を呼び出すときに、文字列をエンコードしてしまっているのに気づきました。
<code>compile()</code> の動作を調べて見たところ</p>
<pre class="prog">
&gt;&gt;&gt; c = compile(&quot;&quot;&quot;u'あ'&quot;&quot;&quot;, &quot;foo.py&quot;, 'single')
&gt;&gt;&gt; c.co_consts
(u'\xe3\x81\x82', None)
&gt;&gt;&gt; c = compile(u&quot;&quot;&quot;u'あ'&quot;&quot;&quot;, &quot;foo.py&quot;, &quot;single&quot;)
&gt;&gt;&gt; c.co_consts
(u'\u3042', None)
</pre>
<p>ビンゴです。</p>
<p>ということで、<code>IPython/iplib.py</code> に次の修正をすることで、IPythonでUnicodeリテラルが気持ちよく使えるようになります</p>
<pre class="prog">
--- iplib.py.old    2009-03-13 15:42:33.000000000 +0900
+++ iplib.py        2009-03-13 15:42:58.000000000 +0900
&#64;&#64; -2019,9 +2019,9 &#64;&#64;
         # this allows execution of indented pasted code. It is tempting
         # to add '\n' at the end of source to run commands like ' a=1'
         # directly, but this fails for more complicated scenarios
-        source=source.encode(self.stdin_encoding)
-        if source[:1] in [' ', '\t']:
-            source = 'if 1:\n%s' % source
+        #source=source.encode(self.stdin_encoding)
+        if source[:1] in [u' ', u'\t']:
+            source = u'if 1:\n%s' % source

         try:
             code = self.compile(source,filename,symbol)
</pre>
<p>Windows (Python 2.6.1, IPython 0.9.1) でもうまく動くか確認して見ました</p>
<pre class="prog">
In [1]: u&quot;あ&quot;
Out[1]: u'\u3042'

In [2]: u&quot;ソ&quot;
Out[2]: u'\u30bd'
</pre>
<p>バッチリです</p>
</div>
<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51389536.html">
<title>bitsliceによる超高速ビット演算</title>
<link>http://dsas.blog.klab.org/archives/51389536.html</link>
<description>bitslice とは
Hack the Cell '09 に参加して知った、Cellに限らず一般的に使えるビット演算の高速化手法について紹介します。
Bitslice と呼ばれる手法では、ビット順を90度回転します。言葉で説明するよりもコードを見たほうが早いので、回転させるコードの例を見てくだ...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-11T16:27:40+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[<h3><a id="id1" name="id1">bitslice とは</a></h3>
<p>Hack the Cell '09 に参加して知った、Cellに限らず一般的に使えるビット演算の高速化手法について紹介します。</p>
<p>Bitslice と呼ばれる手法では、ビット順を90度回転します。言葉で説明するよりもコードを見たほうが早いので、回転させるコードの例を見てください</p>
<pre class="prog">
int   x[32], y[32]; // x が元のデータ、y が回転後のデータ.
for (int i = 0; i &lt; 32; ++i) {
    int t = 0;
    for (int j = 0; j &lt; 32; ++j)
        t |= ((x[j] &gt;&gt; i) &amp; 1) &lt;&lt; j; // x[j] の i ビット目を
    y[i] = t;                        // y[i] の j ビット目にする
}
</pre>
<p>この変換をすることで、y[0] には x[0] - x[31] の最下位ビットが、 y[1] には 2番目のビットが格納されることになります。</p>
<p>回転することでビット演算が高速になる様を見てみます。</p>
<pre class="prog">
//--
// and 演算

// 通常
for (int i = 0; i &lt; 32; ++i) {
    x[i] &amp;= 3; // load, and, store, 各32回
}

// bitslice
for (int i = 2; i &lt; 32; ++i) {
    y[i] = 0; // store 30回
}

//--
// xor 演算

// 通常
for (int i = 0; i &lt; 32; ++i) {
    x[i] ^= 0xff; // load, xor, store, 各32回
}

// bitslice
for (int i = 0; i &lt; 8; ++i) {
    y[i] = ~y[i]; // load, not, store 各8回
}

//--
// シフト演算
for (int i = 0; i &lt; 32; ++i) {
    x[i] &gt;&gt;= 16; // load, 右シフト, store, 各32回
}

// bitslice
for (int i = 0; i &lt; 16; ++i) {
    y[i] = y[i+16]; // load, store, 各16回
}
</pre>
<h3><a id="id2" name="id2">bitslice はなぜ速いか</a></h3>
<h4><a id="id3" name="id3">無駄なビットに対する演算を省略できる</a></h4>
<p>たとえば、 x ^= 1 (xは32bit整数) という演算は、最下位ビットを反転させているだけで、最下位以外の31bitにはまったく影響がありません。せっかくの32bit演算なのに、実質は1bit演算になってしまっているわけです。</p>
<p>bitslice なら最下位ビットだけを集めた32bitに対して演算するので、32bit演算の能力を無駄にすることがありません。</p>
<h4><a id="id4" name="id4">マスクがいらない</a></h4>
<p>マスクは操作したくないビットを保護するためのものです。操作したいビットが集まっていれば、マスクが不要です。</p>
<p>マスク付きの通常ビット演算とbitsliceでの演算の対応は次のようになります。</p>
<ul class="simple">
<li>and演算は、マスクビットが0の場所への 0 代入に</li>
<li>or演算は、マスクビットが1の場所への 1 代入に</li>
<li>xor演算は、マスクビットが1の場所への not 演算に</li>
</ul>
<h4><a id="load" name="load">load が減る</a></h4>
<p>普通の and や or 演算においてロードが必要なのは、操作しない(マスクされた)ビットを元の値にしておくためです。bitsliceでは全bitに1や0を代入できるので、不要な load を減らすことができます。</p>
<p>load が減るということは、単純に命令数が削減する以上の意味があります。一般的に言って、store命令は遅延して次の命令と並列に実行できるのに対して、load命令は完了するまでloadした値に依存する命令を実行できません。load命令が減ることで、パイプラインストールを減らすことができます。</p>
<h4><a id="id5" name="id5">工夫次第でさらに速く</a></h4>
<p>先ほどの例では、通常のシフト演算を配列内での移動に置き換えていました。しかし、 y[i] = y[i+16] の代わりに y += 16 が許されるのであれば、シフト演算は完全に省略できることになります。</p>
<p>同じように or 演算でも、 y[i] = 0 をする代わりに、次に y[i] を参照する場所を 0 に置き換えることができるかもしれません。状況によって、いろいろな工夫が考えられます。</p>
<h3><a id="id6" name="id6">bitslice が苦手な計算</a></h3>
<p>bitslice では各ビットがバラバラになっているので、ビット単位の演算は得意な代わりに、ビットをまたがる演算が苦手です。たとえば加算や減算は繰り上がりや繰り下がりがビットをまたぐので、bitsliceでは遅くなります。試しに加算を実装してみます</p>
<pre class="prog">
// 通常の演算
for (int i = 0; i &lt; 32; ++i) {
    x[i] += z;
}

// bitslice
int carry = 0;
for (int i = 0; i &lt; 32; ++i) {
    int c;
    c = (carry &amp; y[i]) | (y[i] &amp; z) | (z &amp; carry);
    y[i] = carry ^ y[i] ^ z;
    carry = c;
}
</pre>
<p>ただし、特定の条件では通常の演算に近い速度が出せることもあります。次の例では、CPUに bitcnt() という bit が 1 になっている数を数える命令があると仮定して、配列の合計値を計算しています</p>
<pre class="prog">
// 通常の演算
int sum = x[0]; // load 1回
for (int i = 1; i &lt; 32; ++i) {
    sum += x[i];  // load, add, 各31回
}

// bitslice
int sum = bitcnt(y[0]); // load, bitcnt, 各1回
for (int i = 1; i &lt; 32; ++i) {
    sum += bitcnt(y[i]) &lt;&lt; i; // load, bitcnt, shift, add 各31回
}
</pre>
<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51389200.html">
<title>Hack the Cell '09 課題提出しました</title>
<link>http://dsas.blog.klab.org/archives/51389200.html</link>
<description>Hack the Cell '09 に参戦していました。Fixstars社からの結果発表を待ってから成績報告をしようと思っていたのですが、他の参加者の皆さんがどんどんとスコアや素晴らしいテクニックを披露されているので、予定を前倒しして私のスコアとソースコードを公開します。（中身に...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-10T19:26:19+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[<p><a href="http://dsas.blog.klab.org/archives/51368711.html">Hack the Cell '09 に参戦していました。</a>Fixstars社からの結果発表を待ってから成績報告をしようと思っていたのですが、他の参加者の皆さんがどんどんとスコアや素晴らしいテクニックを披露されているので、予定を前倒しして私のスコアとソースコードを公開します。（中身に関してはまた別の記事に書きます）</p>
<h3><a id="id1" name="id1">提出物とスコア</a></h3>
<p><a href="http://lab.klab.org/files/cell/htc09.tar.bz2">ソースコード</a> (試行錯誤の跡が整理されていません)</p>
<p>スコア</p>
<pre class="terminal">
ORIGNAL:         sum=3c927c56, 294030647 ticks
MINE:            sum=3c927c56, 4464381 ticks
ORIGNAL:         sum=2e987a4d, 424155603 ticks
MINE:            sum=2e987a4d, 6440068 ticks
ORIGNAL:         sum=ef1b6aef, 312102737 ticks
MINE:            sum=ef1b6aef, 4738888 ticks
ORIGNAL:         sum=eedd2516, 290055058 ticks
MINE:            sum=eedd2516, 4403913 ticks
ORIGNAL:         sum=f7e967a8, 14366822 ticks
MINE:            sum=f7e967a8, 218363 ticks
ORIGNAL:         sum=1f37a7db, 214216185 ticks
MINE:            sum=1f37a7db, 3252580 ticks
ORIGNAL:         sum=c7d41f36, 294964206 ticks
MINE:            sum=c7d41f36, 4478494 ticks
ORIGNAL:         sum=aa9d2e9f, 259565045 ticks
MINE:            sum=aa9d2e9f, 3941212 ticks
ORIGNAL:         sum=8abd398a, 250844221 ticks
MINE:            sum=8abd398a, 3808729 ticks
ORIGNAL:         sum=a374bd58, 6110290 ticks
MINE:            sum=a374bd58, 92978 ticks
</pre>
<p>倍率としては、約66倍といったところです。ただし、ORIGINALの速度が安定しない(プログラムのアライメントによって実行速度が変化する)ので、倍率は参考程度にとどめておいてください。</p>
<h3><a id="id2" name="id2">今回のコンテストの内容について</a></h3>
<p>課題は、メルセンヌツイスターという乱数生成機の高速化でした。</p>
<p>最適化する対象となる関数はこちらです(一部省略)</p>
<pre class="prog">
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */

static unsigned long mt[N]; /* the array for the state vector  */
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */

/* ... */

unsigned long genrand_int32(void)
{
    unsigned long y;
    static unsigned long mag01[2]={0x0UL, MATRIX_A};
    /* mag01[x] = x * MATRIX_A  for x=0,1 */

    if (mti &gt;= N) { /* generate N words at one time */
        int kk;

        for (kk=0;kk&lt;N-M;kk++) {
            y = (mt[kk]&amp;UPPER_MASK)|(mt[kk+1]&amp;LOWER_MASK);
            mt[kk] = mt[kk+M] ^ (y &gt;&gt; 1) ^ mag01[y &amp; 0x1UL];
        }
        for (;kk&lt;N-1;kk++) {
            y = (mt[kk]&amp;UPPER_MASK)|(mt[kk+1]&amp;LOWER_MASK);
            mt[kk] = mt[kk+(M-N)] ^ (y &gt;&gt; 1) ^ mag01[y &amp; 0x1UL];
        }
        y = (mt[N-1]&amp;UPPER_MASK)|(mt[0]&amp;LOWER_MASK);
        mt[N-1] = mt[M-1] ^ (y &gt;&gt; 1) ^ mag01[y &amp; 0x1UL];

        mti = 0;
    }

    y = mt[mti++];

    /* Tempering */
    y ^= (y &gt;&gt; 11);
    y ^= (y &lt;&lt; 7) &amp; 0x9d2c5680UL;
    y ^= (y &lt;&lt; 15) &amp; 0xefc60000UL;
    y ^= (y &gt;&gt; 18);

    return y;
}
</pre>
<p>しかし、最適化したコードを実装する側のスケルトンとなる関数は次のような定義になっていました</p>
<pre class="prog">
unsigned int
genrand_mine(int num_rand)
{
  int r = 0;
  /* r = num_rand 個の乱数のチェックサム */
  return r;
}
</pre>
<p>この関数は戻り値として、 num_rand 個の生成された乱数のチェックサムを返す必要があります。</p>
<p>もともとの課題では、「※疑似乱数列は、メルセンヌ・ツイスタの実装 mt19937ar.c と同じ乱数列を生成してください。」となっていたのですが、参加者によって以下のように異なった解釈がされていました。</p>
<ul class="simple">
<li>同じ32bit整数としての乱数を求められている (私はこの解釈をしていました)</li>
<li>乱数のビット順がどうなっていても良い</li>
<li>そもそも配布されているプログラムがチェックサムしか見ていないのだから、チェックサムだけ合ってれば何をしてもOK</li>
</ul>
<p>この解釈の違いが問題になっていたのですが、最終的には現在課題のページにあるように、一番ゆるい「チェックサムが合っていれば何をしてもOK」というルールで優勝・準優勝を決め、きちんと乱数を生成していた人にはFixstars社の判断で「フィックススターズ賞」が送られることになりました。</p>
<p>結果として、今回のコンテストにおいて最適化の方針として3つが生まれました。</p>
<ol>
<li><p>元のコードをそのままSIMD化する</p>
<p>基本は元のプログラムのまま、mt[] の要素を4つひとまとめに処理する。
その後、命令数を削減したりパイプラインを埋めて速度を稼いでいく。
この方法だと、60倍～70倍程度までを目指せます。</p>
<p>元の乱数生成器と同じ32bit整数で乱数を生成するので、フィックススターズ賞ねらいになります。</p>
</li>
<li><p>ビット順を90度入れ替えた bitsliece と呼ばれる構造で乱数を計算する</p>
<p>SPUの128bitレジスタを、32bit整数4つとしてではなくて、1bitが128個あると考えて最適化していきます。命令の組み合わせだけでなくデータ構造をどうするのかにも工夫が必要になります。この方法で100倍を超えた参加者もおられるようです。</p>
<p>この方法では乱数が32bit整数の形では出現しないので、優勝・準優勝ねらいになります。</p>
</li>
<li><p>乱数を生成しないで直接チェックサムを計算する</p>
<p>mt[] の値は 32bit整数を乱数の種として初期化されるので、種と num_rand と組み合わせた 64bitの情報から結果のチェックサム32bitを求めるということが究極的な目標になります。
極端な例を言えば 32bit * 2^64 分のテーブルを用意すれば、O(1) でチェックサムの計算ができる事になります。</p>
<p>私には全く思いつかなかったのですが、 この計算をメモリ制約の中で O(n) 未満で実行する方法が存在するかもしれません。</p>
</li>
</ol>
<p>私は2月は忙しくて全く高速化できなかったので、ルール確定前までに書いていた 1 の方法のプログラムのまま提出しました。
提出締め切り後、同じ1の方法でもあと5%以上高速化する方法が他の参加者のブログで紹介されていて悔しい思いをしています。
次回があればまた参加したいと思います。</p>
<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51388703.html">
<title>日経Linuxで連載を始めました。</title>
<link>http://dsas.blog.klab.org/archives/51388703.html</link>
<description>
本日発売される日経Linux 4月号からKLab の社員で執筆した「2000円ルーターを改造しよう」という連載が始まります。


日経 Linux (リナックス) 2009年 04月号




この連載では 2000円～4000円で購入できる無線LANルーター La Fonera に DD-Wrt や OpenWrt などの...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-09T09:03:41+09:00</dc:date>
<dc:subject>KLab</dc:subject>
<content:encoded><![CDATA[<p>
本日発売される日経Linux 4月号からKLab の社員で執筆した「2000円ルーターを改造しよう」という連載が始まります。
</p>

<a href="http://www.amazon.co.jp/日経-Linux-リナックス-2009年-04月号/dp/B001TEBYV0/"><p>日経 Linux (リナックス) 2009年 04月号</p>
<p><img src="http://ec2.images-amazon.com/images/I/51BkNAH%2B82L._SL500_AA240_.jpg" /></p>
</a>

<p>
この連載では 2000円～4000円で購入できる無線LANルーター La Fonera に DD-Wrt や OpenWrt などの代替ファームウェアに置き換えて活用する方法を紹介していきます。
</p>
<p>
4月号の第1回では、前準備としてFONルーターのブートローダーにシリアル接続する方法や、telnet でログインする方法、などを紹介しています。
</p>
<p>これから安価で自由度の高い無線LANルーターを作ってみたいという方はぜひご覧にな
って下さい。</p>

<hr>
hamano]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51386297.html">
<title>花粉の飛散量を取得する Perlモジュール</title>
<link>http://dsas.blog.klab.org/archives/51386297.html</link>
<description>
すっかり花粉が飛び交う季節になってしまいました。
今や花粉症は5人に1人疾患する症状とも言われており、マスクや薬などによる花粉対策の準備を始めている方が多いのではないかと思います。


そこで、今回はプログラマに出来る花粉対策を紹介したいと思います。
花...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-03-02T15:18:57+09:00</dc:date>
<dc:subject>perl</dc:subject>
<content:encoded><![CDATA[<p>
すっかり花粉が飛び交う季節になってしまいました。
今や花粉症は5人に1人疾患する症状とも言われており、マスクや薬などによる花粉対策の準備を始めている方が多いのではないかと思います。
</p>
<p>
そこで、今回はプログラマに出来る花粉対策を紹介したいと思います。
花粉症対策にはとにかく花粉を吸わないことが重要です。
大量の花粉にばく露されることで、症状が悪化したり、今まで花粉症で無かった人も花粉症が発症する場合があります。
つまり花粉が多く飛んでいる時間帯をなるべく避けることが有効な花粉対策なのですが、
天気予報の花粉飛散情報は1日単位のデータだったりして、参考にならないことが多いです。
</p>

<p>
環境省が運用する<a href="http://kafun.taiki.go.jp/">花粉観測システム(はなこさん)</a>では１時間毎の花粉飛散データが公開されています。
1時間毎に花粉飛散データが更新されるため外出のタイミングを決定するのに役立ちます。
プログラマであれば、このデータを cron で定期的に監視して警告メールを送ったり、Shell のプロンプトやemacs のミニバッファに表示させたい、と思うはずです。
</p>
<p>
そこで、この花粉観測システムはなこさんから花粉飛散データを取得する perl module を作成しました。
</p>
<p><a href="http://search.cpan.org/~hamano/WWW-Hanako-0.05/">
WWW::Hanako - Perl interface for Hanako(Pollen observation system at Japan) - search.cpan.org
</a><p>

<p>
この perlモジュールを使用する前に、まずお近くの観測所コードを調べる必要があります。
東京の観測所コードは以下の通りです。
</p>

<table>
<tr><td>エリアコード</td><td>観測所コード</td><td>観測所</td></tr>
<tr><td>3</td><td>51310200</td><td>東京都多摩小平保健所</td></tr>
<tr><td>3</td><td>51320100</td><td>独立行政法人森林総研多摩森林科学園</td></tr>
<tr><td>3</td><td>51300100</td><td>日本医科大学付属多摩永山病院</td></tr>
<tr><td>3</td><td>51300200</td><td>日本医科大学付属病院</td></tr>
</table>

<p>
例えば、日本医科大学付属病院での観測情報を得るコードは以下の様になります。
</p>

<pre class="prog">
use WWW::Hanako;
my $hanako = WWW::Hanako->new(area=>3, mst=>51300200);
print $hanako->now()->{pollen} . "\n";
</pre>

<p>
表示される、飛散量の数値は個／m^3中に観測された花粉数の１時間平均、となります。
この数値が1000を越えた場合、かなり危険なので十分注意して外出しましょう。
</p>
<p>
また、この花粉観測システム(はなこさん)のデータは転用や営利目的とした利用を禁止していますので、あくまで個人利用に限るよう注意してください。
</p>

<p>
参考サイト:
<a href="http://www.env.go.jp/chemi/anzen/kafun/html/001.html">
花粉症環境保健マニュアル－２００９年２月改定版－
</a>
<p>

<hr>
hamano]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51385301.html">
<title>WSGIServerを3行でマルチスレッド化する</title>
<link>http://dsas.blog.klab.org/archives/51385301.html</link>
<description>WSGIとは

PythonでWebアプリを作るときに必ず出てくる単語にWSGIがあります。
WSGIとは、Web Server Gateway Interface の略で、WebサーバーとPython製Webアプリを
つなげる標準インタフェースです。

WSGIの上で動くようにアプリケーションを作ると、そのアプリケー...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-02-27T17:40:46+09:00</dc:date>
<dc:subject>Python</dc:subject>
<content:encoded><![CDATA[<h3>WSGIとは</h3>
<p>
PythonでWebアプリを作るときに必ず出てくる単語にWSGIがあります。
WSGIとは、Web Server Gateway Interface の略で、WebサーバーとPython製Webアプリを
つなげる標準インタフェースです。</p>
<p>
WSGIの上で動くようにアプリケーションを作ると、そのアプリケーションは修正無しに
Apache+mod_wsgi, Apache+mod_python, fastcgi, scgi, cgi, 等の環境で動かせるように
なります。</p>
<p>
他にもミドルウェアという考え方があります。例えばOpenID認証機能をWebフレームワークの
プラグインとして開発した場合では他のWebフレームワークでは利用できないのですが、
WSGIミドルウェアとして開発すればWebフレームワークを問わずに利用できるようになります。
</p>

<h3>標準ライブラリのwsgirefモジュール</h3>
<p>
Python2.5から、標準ライブラリにwsgirefモジュールが追加されました。その中にはWSGIサーバーも
入っているので、自分で書いたWSGIアプリを手軽に立ち上げたいときに重宝します。
</p>
<p>
次のコードは、簡単なWSGIサーバー+アプリの例です。
</p>
<pre class="prog">
from wsgiref.simple_server import *

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['hello']

server = make_server('0.0.0.0', 8000, myapp)
server.serve_forever()
</pre>
<h3>WSGIServerのマルチスレッド化</h3>
<p>
上記のコードで立ち上がるWebサーバーは、シングルスレッド&amp;シングルプロセスで動作しているので、
複数のクライアントからアクセスされた場合に問題があります。接続が遅かったり不安定だったりする
クライアントが一つでも合った場合、その接続が完了するか切断するまで他の接続ができないので、
接続に失敗したり数十秒かかったりすることになります。
</p>
<p>
普通はWebアプリを公開する場合には標準ライブラリのWSGIServerではなくて別のサーバーを使う
ものですが、お手軽な方法として3行追加と1行修正のみで、他のライブラリ無しに
マルチスレッド化したりマルチプロセス化することが出来ます。
次のコードが上記のコードをマルチスレッド化したものになります。
</p>
<pre class="prog">
from wsgiref.simple_server import *
from SocketServer import *
class ThreadingWsgiServer(ThreadingMixIn, WSGIServer):
    pass

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['hello']

server = make_server('0.0.0.0', 8000, myapp, ThreadingWsgiServer)
server.serve_forever()
</pre>
<p>
このコードについて簡単に説明します。
wsgiref.simple_server.make_server は第三引数でサーバークラスを指定することができて、
デフォルト値は wsgiref.simple_server.WSGIServer になっています。
WSGIServerの継承関係は次のようになっています。
</p>
<pre style="background-color: #ddd;">
SocketServer.BaseServer
  ↑
SocketServer.TCPServer
  ↑
BaseHTTPServer.HTTPServer
  ↑
wsgiref.simple_server.WSGIServer
</pre>
<p>
SocketServerモジュールには、ThreadingMixIn, ForkingMixIn というクラスがあり、
SocketServer.BaseServer を継承したサーバークラスであれば簡単にマルチスレッド化
したりfork化したりできるようになっています。
WSGIServer も BaseServer を継承しているので、ThreadingMixIn/ForkingMixIn クラスを
Mix-in してやるだけでマルチスレッド化やマルチプロセス化が可能です。
</p>
<p>小さなテクニックですが、Webアプリが完成するまではサーバーの設定の問題とアプリの
問題が混ざらないようにしたいときとか、Webサーバーの設定ファイルを書くのに慣れてなくて
後回しにしたいときに重宝します。</p>

<p>
ちなみに、 <a href="http://trac.saddi.com/flup">flup</a> というライブラリには、
thread pool や prefork を使ったWSGIサーバーがあって十分実用になる速度が出るので、
標準ライブラリのサーバーだと遅いという時に利用できます。
</p>
<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51380201.html">
<title>「WinAmulet」バージョンアップのお知らせ</title>
<link>http://dsas.blog.klab.org/archives/51380201.html</link>
<description>昨年このブログ上で公開した Windows 用フリーソフトウェア「WinAmulet」をバージョンアップしました。




旧バージョンをご利用中の方も、初めての方も、ぜひ新しい WinAmulet をお試し下さい。
WinAmulet のページ


ダウンロードはこちらから





■ こ...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-02-13T11:34:53+09:00</dc:date>
<dc:subject>win</dc:subject>
<content:encoded><![CDATA[昨年このブログ上で公開した Windows 用フリーソフトウェア「<a href="http://dsas.blog.klab.org/archives/51301907.html">WinAmulet</a>」をバージョンアップしました。

<p>
<img src="http://image.blog.livedoor.jp/klab_gijutsu2/imgs/7/6/76919e24.png" alt="WinAmulet0.9.3.0">

旧バージョンをご利用中の方も、初めての方も、ぜひ新しい WinAmulet をお試し下さい。
<center><a href="http://dsas.blog.klab.org/archives/51301907.html">WinAmulet のページ</a>
<br>
<br>
<a href="http://dsas.blog.klab.org/archives/51301907.html#platforms">ダウンロードはこちらから</a>
</center>

<br>
<a name="whatsnew"></a>
<p>
<b>■ このプログラムの概要</b>

<p>
「WinAmulet」は、特定のフォルダに対してアクセスを許可するプログラムを指定することにより、対象フォルダ下のファイルを意図しないプログラムによるアクセスから保護することが可能なソフトウェアです。

<p>
<b>■ 更新内容</b>
</p>
バージョン 0.9.2.0 -&gt; 0.9.3.0 での更新内容は以下の通りです。
<br>
<ul>
<li>内部エンジンの性能向上により稼動中の動作がさらに軽快になりました
<li>アクセス違反検出時には従来のバルーンメッセージに加えタスクトレイアイコンの点滅で通知します
<li>リダイレクト先のダミーフォルダを任意に設定可能となりました
<li>旧バージョン利用中のユーザーはバージョンアップにより引き続きWinAmuletをご利用頂けます
</ul>
<hr>
(tanabe)
]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51368711.html">
<title>Hack the Cell '09 に参戦します</title>
<link>http://dsas.blog.klab.org/archives/51368711.html</link>
<description>
PS3でLinuxが動く！ SPUとかいう面白いプロセッサのプログラムを自分で書いて動かせる！ということで、
KLabでもPS3を購入していたのですが、最近あまり有効に活用されていませんでした。


何か良い使い道無いかなと思っていたところ、 Fixstars が開催している 
&quot;Ha...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2009-01-13T18:07:49+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[<p>
PS3でLinuxが動く！ SPUとかいう面白いプロセッサのプログラムを自分で書いて動かせる！ということで、
KLabでもPS3を購入していたのですが、最近あまり有効に活用されていませんでした。

<p>
何か良い使い道無いかなと思っていたところ、 Fixstars が開催している 
<a href="http://cell.fixstars.com/challenge/index.html">"Hack the Cell '09 - Cell Programming Contest"</a>
を見つけて、他の社員も誘って参加することにしました。

<p>
私はSPUのプログラムを書くのは初めてだったのですが、Fixstars,SCEI,IBMのサイトの情報を参考にしながら
C言語拡張機能を使ってSPU SIMDのプログラムを書いてみました。

<p>
触ってみた感想ですが、まず、32bit固定長の3オペランド命令群と128bitレジスタの組み合わせが
非常に気持ちいいです。今まで触ったことのあるCPUは2オペランドマルチバイト命令ばかりだったので、
3オペランドだとmov命令が要らないのが新鮮でした。C言語上で spu_??? という関数を使うと、ほぼ1対1で
機械語に置き換わっていき、あとはコンパイラが適切にレジスタ割り当てやパイプラインを意識した
命令語順の並べ替えを行っていきます。
spu_timing というツールでパイプラインの利用の仕方を可視化することができ、
Dual Issue（2つのパイプライン両方への命令発行に成功した状態）がきれいに並んでいると胸のすくような思いです。

<p>
また、予測不可能な割り込み、キャッシュミス、TLBミス等が存在しないので、同じコードを同じ条件で動かすと
必ず同じクロック数で完了するのも面白いです。 x86 ではCPUの種類がたくさんあるので、あるCPUに最適化すると
他のCPUで遅くなることがあり、早い段階で「これ以上最適化しても意味ないや」と満足してしまっていました。
SPUでは数%、数サイクルの最適化まで詰めていくことができますが、そうすると「これ以上命令削れない」と
思っていた部分が後のひらめきで削れたりするので、今まで自分がどれだけいいかげんに「最適化」という単語を
使っていたのかを思い知らされました。

<p>
3/20の結果発表後、入賞したKLab社員による参戦レポートをこのBlog上で公開していくつもりです。
3/6の課題提出締め切りまでまだ時間があるので、腕に覚えのある方は一緒に挑戦してみませんか？

<hr>
<div style="margin: 1px 3px 1px 0px; text-align: right;">@methane</div>]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51361402.html">
<title>MAKUOSANバージョンアップのお知らせ(Ver1.1.2)</title>
<link>http://dsas.blog.klab.org/archives/51361402.html</link>
<description>
MAKUOSAN をバージョンアップしましたのでお知らせします。
主な変更点は以下のとおりです。


【Ver1.1.1→Ver1.1.2】

シャットダウンメッセージを送出しない不具合を修正

Ver1.1.1には、makuosanの終了通知が送出されないという不具合がありました。そのため、...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2008-12-24T17:48:48+09:00</dc:date>
<dc:subject>運用</dc:subject>
<content:encoded><![CDATA[<P>
<A href="http://lab.klab.org/wiki/Makuosan">MAKUOSAN</A> をバージョンアップしましたのでお知らせします。<BR>
主な変更点は以下のとおりです。
</P>
<P>
<B>【Ver1.1.1→Ver1.1.2】</B>
<DL>
<DT>シャットダウンメッセージを送出しない不具合を修正</DT>
<DD>
Ver1.1.1には、makuosanの終了通知が送出されないという不具合がありました。そのため、makuosanを終了しても、しばらくの間メンバーリストに残ってしまうという問題がありましたが、これを修正しました。
</DD>
</DL>
</P>
<P>
<B>【Ver1.0.1→Ver1.1.1】</B>
<DL>
<DT>msyncコマンドに--deleteオプションを追加</DT>
<DD>
送信元に存在しないファイルを転送先で消すことができるようになりました。
</DD>
<BR>
<DT>転送速度が向上</DT>
<DD>
ファイル転送速度が約1.5倍（当社比）になりました。<BR>
1対1での速度はまだscpにかないませんが、今後も随時改善していきます。<BR>
</DD>
<BR>
<DT>エラーレポートを詳細に表示</DT>
<DD>
転送先で発生したエラーなどを詳細に表示するようにしました。
</DD>
</DL>
</P>
<P>
<B><FONT COLOR=RED>
【注意】<BR>
Ver1.0系とVer1.1系ではプロトコルに互換性がありません。<BR>
バージョンアップの際は全サーバに対して実施して下さい。<BR>
</FONT></B>
<BR>
MAKUOSAN の詳細につきましては<a href="http://lab.klab.org/wiki/Makuosan">プロ
ジェクトサイト</a>を参照してください。
</P>
<BR>
<P>
<B>新機能の使用例</B>
<HR>
rsyncと同名のオプションなのでピンときた方もいると思いますが、
今回追加した--deleteオプションの使用例をご紹介します。
</P>
まずは、送信元サーバ（以下src）に適当にファイルを作ります。
<PRE CLASS="terminal">
src:~$ mkdir hoge
src:~$ mkdir hoge/test1
src:~$ mkdir hoge/test2
src:~$ mkdir hoge/test3
src:~$ touch hoge/test1/aaa
src:~$ touch hoge/test1/bbb
src:~$ touch hoge/test1/ccc
src:~$ touch hoge/test2/12345
src:~$ find hoge/
hoge/
hoge/test1
hoge/test1/aaa
hoge/test1/bbb
hoge/test1/ccc
hoge/test2
hoge/test2/12345
hoge/test3
</PRE>
</P>
<P>
srcと転送先サーバ（以下dst）でmakuosanを起動します。
<PRE CLASS="terminal">
src:~$ makuosan -b ./
</PRE>

<PRE CLASS="terminal">
dst:~$ makuosan -b ./
</PRE>
</P>
<P>
srcからdstへhogeを転送します。
<PRE CLASS="terminal">
src:~$ msync -rv hoge
update dst:hoge/test1/aaa
update dst:hoge/test1/bbb
update dst:hoge/test1/ccc
update dst:hoge/test2/12345
update dst:hoge/test3
update dst:hoge/test1
update dst:hoge/test2
update dst:hoge
</PRE>
</P>
dstにhogeが転送されていることを確認します。
<PRE CLASS="terminal">
dst:~$ find hoge/
hoge/
hoge/test1
hoge/test1/ccc
hoge/test1/aaa
hoge/test1/bbb
hoge/test2
hoge/test2/12345
hoge/test3
</PRE>
</P>
<P>
srcでhoge/test1を削除します。
<PRE CLASS="terminal">
src:~/work$ rm -fr hoge/test1
src:~/work$ find hoge
hoge
hoge/test2
hoge/test2/12345
hoge/test3
</PRE>
</P>
<P>
--deleteオプションを付けて再度転送します。
<PRE CLASS="terminal">
src:~$ msync -rv --delete hoge
delete sag14:hoge/test1/ccc
delete sag14:hoge/test1/aaa
delete sag14:hoge/test1/bbb
delete sag14:hoge/test1
update sag14:hoge
</PRE>
</P>
<P>
dstでもhoge/test1が消えています。
<PRE CLASS="terminal">
dst:~$ find hoge/
hoge/
hoge/test2
hoge/test2/12345
hoge/test3
</PRE>
</P>
]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51353125.html">
<title>KLab の若手エンジニアがブログを始めました</title>
<link>http://dsas.blog.klab.org/archives/51353125.html</link>
<description>この度、KLab(株)の若手エンジニアがブログを始めることになりました。

KLab若手エンジニアの これなぁに？

日々の業務における技術的トピックや、何気なく使っている便利なライブラリの内部で行われている処理を覗いた時のハナシ。これ等をブログというカタチで面白い...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2008-12-02T14:41:04+09:00</dc:date>
<dc:subject>開発</dc:subject>
<content:encoded><![CDATA[<P>この度、KLab(株)の若手エンジニアがブログを始めることになりました。</P>
<P>
<B><a href="http://lab.klab.org/young/" target="_blank">KLab若手エンジニアの これなぁに？</a></B>
</P>
<P>日々の業務における技術的トピックや、何気なく使っている便利なライブラリの内部で行われている処理を覗いた時のハナシ。これ等をブログというカタチで面白いものを発信できるのでは、という発想からこのブログをはじめることとなりました。</P>

<b>【投稿済みの記事やテーマ】</b>
<dl>
<a href="http://lab.klab.org/young/2008/11/symfony-%c3%97-mysql-%e6%96%87%e5%ad%97%e3%82%b3%e3%83%bc%e3%83%89%e3%81%a7%e9%9d%a2%e7%99%bd%e3%81%84%e4%ba%8b%e8%b1%a1/" target="_blank">symfony × MySQL × Shift_JIS: 0×5c関連</a>
<dd>
0×5c問題について書いてみました。<br>
他にもsymfonyのトランザクションについても書いています。
PHPやsymfonyについての記事はこれからどんどん書いていく予定です！<br>
</dd>
<br>
<a href="http://lab.klab.org/young/2008/11/rhino%e3%82%92%e4%bd%bf%e3%81%8a%e3%81%86/" target="_blank">Rhinoを使おう</a>
<dd>
拡張性とポータビリティにすぐれた JavaScript 処理系 Rhino(ライノー)を紹介しています。
JavaScriptやActionScript、Flex等RIAに関する記事等もどんどん書いていきます！<br>
</dd>
<br>
<a href="http://lab.klab.org/young/2008/12/cc-%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%89%e3%82%92-flash-player-%e4%b8%8a%e3%81%a7%e5%8b%95%e3%81%8b%e3%81%99-alchemy/" target="_blank">C/C++ のコードを Flash Player 上で動かす Alchemy</a>
<dd>
先日 Adobe Labs がプレビューリリースしたAlchemy というプロジェクトを試した記事です。
新しい技術に挑戦した際のトピックスなども織り交ぜていきます。<br>
</dd>
</DL>
<br>
<p>まだまだ未熟な若手エンジニアですが、技術・知識に対するアグレッシヴなアプローチや新しいものを試すチャレンジ等見どころ満載なブログです！
</p>
<p>コメントなど大歓迎です、ぜひチェックしてください！！</p>
]]>
</content:encoded>
</item>
<item rdf:about="http://dsas.blog.klab.org/archives/51345077.html">
<title>まくおをFreeBSDやMacOSXでも動くようにしました</title>
<link>http://dsas.blog.klab.org/archives/51345077.html</link>
<description>
先日公開したまくおさんですが、
Linux以外の環境では全然ビルドが通らないことに公開後に気がつきました。
気になって気になって夜も寝れなかったので(笑）、手元にあったFreeBSD7.0とMacOSX10.4でも動くようにしてみました。


makuosan-1.0.1のダウンロードはこち...</description>
<dc:creator>klab_gijutsu2</dc:creator>
<dc:date>2008-11-12T12:50:05+09:00</dc:date>
<dc:subject>開発</dc:subject>
<content:encoded><![CDATA[<P>
<a href="http://dsas.blog.klab.org/archives/51342234.html">先日公開したまくおさん</a>ですが、
Linux以外の環境では全然ビルドが通らないことに公開後に気がつきました。
気になって気になって夜も寝れなかったので(笑）、手元にあったFreeBSD7.0とMacOSX10.4でも動くようにしてみました。
</P>
<UL>
<li><b><a href="http://lab.klab.org/wiki/Makuosan">makuosan-1.0.1のダウンロードはこちら</a></b></li>
</UL>
<P>
また、<a href="http://www.sssg.org/blogs/naoya/archives/963">specファイルと起動スクリプトを頂きました</a>
ので同梱しておきます。<br>
これは、とても助かります！、ありがとうございます！＞Naoyaさん<br>
</P>
<P>
というわけで、今回は「LinuxではビルドできるけどFreeBSDではエラーになる点」をいくつか紹介したいと思います。
</P>
</P>
<H3>
<A HREF="http://www.linux.or.jp/JM/html/LDP_man-pages/man3/ftime.3.html">ftime</A> を
<A HREF="http://www.linux.or.jp/JM/html/LDP_man-pages/man2/gettimeofday.2.html">gettimeofday</A> に変更
</H3>
<HR>
何を血迷っていたのか、現在時刻を取得するためにftimeを使っている箇所がありました。
マニュアルにもきちんと「この関数は古いものである。使ってはならない。秒単位の時間で十分なら、 time(2) が利用できる。 gettimeofday(2) でマイクロ秒が得られる」って書いてありますね。
</P>
<P>
<H3>
<A HREF="http://www.linux.or.jp/JM/html/LDP_man-pages/man3/tzset.3.html">tzset</A> 後のtimezone参照をやめて
<A HREF="http://www.linux.or.jp/JM/html/LDP_man-pages/man3/ctime.3.html">localtime</A> を使うようにした
</H3>
<HR>
makuosan はベースディレクトリにchrootする機能があります（-c オプション）<BR>
また、makuosan のログはsyslog に出力していますが、chrootすると/etc/localtime が見えなくなるため、syslogに記録される
時間が9時間ほどタイムスリップしてしまいます。（たしかproftpdのchroot機能などでも似たような問題があったと思います）
</P>
<P>
しかし、chroot先に/etc/localtimeを勝手にコピーするわけにもいかな
いので、環境変数の"TZ"に"JST-9"のような文字列で時差を設定します。すると、/etc/localtime がなくても日本標準時で
ログが記録されるようになります。
</P>

問題は、環境変数の"TZ"に設定する文字列をどのように生成するかですが、それを以下のようなコードで実装していました。
<PRE CLASS="prog">
extern char *tzname[2];
extern long timezone;

void settzenv()
{
  char TZ[256];
  tzset();
  sprintf(TZ,"%s%+ld",tzname[0],timezone);
  setenv("TZ",TZ,0);
}
</PRE>
tzset するだけで必要な値がグローバル変数に入るので便利だなーなんて軽く考えていましたが、FreeBSDでは同名の関数が
あるのでエラーになってしまいます。
</P>
<P>
そのため、localtime 関数を使ってtm 構造体をセットし、tm_gmtoff メンバとtm_zone 
メンバを利用して文字列を生成するようにしました。
<PRE CLASS="prog">
  time_t ttime;
  struct tm *t;
  char tz[256];
    
  time(&ttime);
  tzset();
  t = localtime(&ttime);
  sprintf(tz, "%s%+ld",   t->tm_zone, -(t->tm_gmtoff/3600));
  setenv("TZ", tz, 0);
</PRE>
</P>
<BR>
<H3>
おまけ： libcryptが必要な理由
</H3>
<HR>
<P>
最後に少しだけ、プロジェクトサイトに書いていなかったことを書いておきます。<BR>
（もちろん後で追記しますが(^^;<BR>
<BR>
makuosanではファイルの同一性をチェックする機能でmd5を使っています。
<PRE CLASS="terminal">
 $ msync --check
</PRE>
</P>
<P>
また、ネットワークに流れるデータを暗号化するためにblowfishを使っています。
<PRE CLASS="terminal">
 $ echo himitsu > keyfile
 $ chmod 400 keyfile
 $ makuosan -b dokka -k keyfile
</PRE>
これらの機能は、opensslのライブラリを利用しているので、ビルドにはopensslの
ヘッダファイルとライブラリが必要です。
</P>

]]>
</content:encoded>
</item>

</rdf:RDF>
