yuryu.jp

life with open mind

2012年1月2日
by Yuryu
0 comments

謹賀新年

新年おめでとうございます。

昨年は転職活動始めてみたものの中途半端になったり、空回りしたりと上手くいかないことも多かったです。今年は飛躍の年にしたいです。

この blog もぼちぼち更新していきますので、今後もどうぞよろしくお願いします。

2011年12月23日
by Yuryu
0 comments

Windows Server on Dell PowerEdge インストール記

Windows Server 2008 R2 を Dell PowerEdge R210 II にインストールする機会があり、私なりに苦労したのでまとめてみます。

構成

本体 Dell PowerEdge R210 II
RAIDカード LSI MegaRAID SAS 9260-4i
HDD Seagate Cheetah 15k.7 600GB * 2 (RAID1)
OS Windows Server 2008 R2 Standard Edition
リモート管理コンソール DELL iDRAC6 Enterprise
起動モード UEFI

Continue Reading →

2011年12月14日
by Yuryu
0 comments

only my railgun サビの和訳

only my railgun をカラオケで歌ったところ、ネイティブに「英語部分の歌詞が意味不明」と言われたので、和訳してみました。
ただし私の英語力なので間違ってるかも。

Looking! The blitz loop this planet to search way, only my railgun can shoot it.

loop の三単現 s がない気がしますが

見てる! 電撃戦が道を探すために、この惑星を輪にする。
私のレールガンだけがそれを撃てる。

Sparkling! The shiny lights awake true desire, …

輝く! 眩しい光が本当の欲望を呼び起こす。 …

確かに意味が分からない。伝えたいこととは違う英語になっている気がする…

2011年12月3日
by Yuryu
0 comments

イベント会場でモバイルWi-Fiを使ってはいけない理由

昨今ポケット Wi-Fi を始めとするモバイルWi-Fiルーターをお使いの方が増えています。日常とても便利なのですが、人が多く集まるイベント会場で使うと会場の無線LANが使えなくなり、迷惑になることがあります。

イベント会場に無線LANがある場合は、そちらを使うようにして、モバイルWi-Fiルーターの電源はOFFにしましょう。

ではなぜ、モバイルWi-Fiルーターを使ってはいけないのでしょうか?

Continue Reading →

2011年11月24日
by Yuryu
0 comments

memtest64 開発メモ

memtest86 という有名なメモリチェッカがあるんですが、これ 64bit に対応していません。
PAE には対応しているので、64GB までのメモリチェックは出来るんですが、お陰で結構複雑なコードになってるし、メモリアクセスは 32bit なので遅い… ということで、64bit 移植に挑戦してみようと思いました。

ところがブートローダーってまともに書いたことが無いので、さっぱりわかりません。
ある程度まとまってきたので、自分用に調査メモを残します。

Continue Reading →

2011年8月4日
by Yuryu
0 comments

Rails はじめました

Rails ずっとやったことなくて、このままじゃいけない気がしたので勉強を始めました。
まずは 公式サイトのチュートリアル をやっています。コマンドを打つだけで色々ファイルが生成されて、魔法みたいですね。

本では Ruby on Rails 3 アプリケーションプログラミング が良さそう。チュートリアル終わったら欲しいな。

がんばるよー。

2011年7月28日
by Yuryu
0 comments

Ackermann function

アッカーマン関数という関数があります。
バカ正直に計算しようとするとすぐ計算量が膨大になり、計算できなくなるたぐいの関数です。

これをアセンブリでバカ正直に計算させるコードを書いてみました。階乗を計算させるコードのおまけ付きです。

実際に実行させたところ、ack(3, 12) あたりになるとスタックがあふれました。
スタックサイズを調整すればもうちょっといけると思います。

使用した高速化のテクニック

  • 末尾再帰を CALL から JMP に置き換え
  • TEST+JE でmacro fusion できる命令形式にした
  • INC / DEC を ADD / SUB に置き換えて、フラグレジスタの依存関係を解消
  • MOV RDX, 1 を MOV EDX, 1 にして命令長を短縮
    .code

ack PROC public

    ; RCX = m, RDX = n
    TEST    RCX, RCX
    JE      m_zero

    TEST    RDX, RDX
    JE      n_zero

    PUSH    RCX
    SUB     RDX, 1
    CALL    ack
    POP     RCX
    SUB     RCX, 1
    MOV     RDX, RAX
    JMP     ack

n_zero:
    MOV     EDX, 1
    SUB     RCX, 1
    JMP     ack

m_zero:
    MOV     RAX, RDX
    ADD     RAX, 1
    RET

    ack ENDP

factorial PROC public

    MOV     EAX, 1
    CMP     RCX, 1
    JLE     f_ret

f_loop:
    IMUL    RAX, RCX
    SUB     RCX, 1
    CMP     RCX, 1
    JNLE    f_loop

f_ret:

    RET

    factorial ENDP

    END

一応 C で書いた以下のコードよりは、3割ぐらい速いようです(Visual C++ 2010 で /O2 としてコンパイル)。階乗は微妙に速いだけでほとんど変わりませんでした。CPU は Penryn ベースの Core2 Duo です。

int64_t factorial_c(int64_t n)
{
    int64_t r = 1;
    while(n > 1) r *= n--;
    return r;
}

int64_t ack_c(int64_t m, int64_t n)
{
    return m == 0 ? n + 1 : n == 0 ? ack_c(m - 1, 1) : ack_c(m - 1, ack_c(m, n - 1));
}

2011年7月25日
by Yuryu
0 comments

Bogosort

世の中にはボゴソート というソートアルゴリズムがあります。ランダムにシャッフルして、順番に並んでいたらソート完了というものです。

魔が差したので実装してみました。

ところで、ボゴソートは完全な乱数を使用した場合にはアルゴリズムが完了することが保証されていますが、疑似乱数には周期があるため同じ状態が繰り返し、完了しない場合があります。メルセンヌツイスタ MT19937 を利用した場合、周期は 2^19937-1 で、およそ 10^6001 です。

一方ボゴソートの平均計算量は O(n * n!) らしいので、138 * 138! = 9.55 * 10^238、つまり 138 要素ぐらいまでならメルセンヌツイスタぐらいの周期を持つ乱数でそろう可能性が高い(50%を越える)ということになります。だいたい計算してみると 2080 * 2080! = 10^6004 ぐらいとのことなので、2079 要素ぐらいまでならメルセンヌツイスタぐらいの周期を持つ乱数でそろう可能性が高い(50%を越える)ということになります。

32bit の線形合同法(普通の rand() 関数)の場合は、最大周期が 2^32-1 なので、わずかに11要素ぐらいまでしかソートできず、それを越えると永久にソートできない可能性が高くなります。

メルセンヌツイスタのような、非常に周期が長いと言われる乱数を利用しても数要素までしかソートできないなんて、ボゴソートは恐ろしいですね。

ちなみに 138要素の場合でも、1秒間に1京回計算できる計算機を使っても、完了までに 10^215年以上かかることになり、宇宙の寿命が先に尽きてしまいます。
2000要素とかどんだけかかるのかな…

#include <iostream>
#include <boost/timer.hpp>
#include <boost/random.hpp>
#include <algorithm>
#include <ctime>
#include <boost/foreach.hpp>

class Random
{
public:
  boost::mt19937 gen;
  boost::uniform_int<int> dst;
  boost::variate_generator< boost::mt19937, boost::uniform_int<int> > rand;
  Random( int N ):// call instance:
    gen( static_cast<unsigned long>(std::time(nullptr)) ), dst( 0, N ), rand( gen, dst ) {
  }
  std::ptrdiff_t operator()( std::ptrdiff_t arg ) {
    return static_cast< std::ptrdiff_t >( rand() );
  }
};

template <class InputIter, class Rand>
void bogosort(InputIter first, InputIter last, Rand rand){
  while(!std::is_sorted(first, last))
    std::random_shuffle(first, last, rand);
}

template <class InputIter>
void bogosort(InputIter first, InputIter last){
  while(!std::is_sorted(first, last))
    std::random_shuffle(first, last);
}

int main(int argc, int argv[])
{
  std::vector<int> a;

  while(true){
    int i = 0;
    std::cin >> i;
    if(std::cin.eof() || std::cin.fail()) break;
    a.push_back(i);
  }
  Random rand(a.size());
  boost::timer timer;
  bogosort(a.begin(), a.end(), rand);
  std::cout << "time = " << timer.elapsed() << std::endl;
  BOOST_FOREACH(int i, a){
    std::cout << i << ", ";
  }
  std::cout << std::endl;
  return 0;
}

2011年6月11日
by Yuryu
0 comments

Boost の 32bit と 64bit ライブラリの両方を用意しておく方法

Boost のほとんどはヘッダファイルだけで動きますが、一部のライブラリはあらかじめビルドしておかなければなりません。

Windows だと x86 と x64 の両方ビルドしたいこともあって、私なりに共存策を探ってみました。Boost 1.46.1 で実行、確認した方法です。
コンパイラは Visual Studio 2010 を利用しました。

C:\usr\local\boost_1_46_1>bootstrap
#略
C:\usr\local\boost_1_46_1>bjam --build-dir=build\x86 --stagedir=stage\x86 address-model=32 -j 2
# 略
C:\usr\local\boost_1_46_1>bjam --build-dir=build\x64 --stagedir=stage\x64 address-model=64 -j 2
# 略

こうすると、c:\usr\local\boost_1_46_1\stage\x86\lib に 32bit バイナリが、c:\usr\local\boost_1_46_1\stage\x64\lib に 64bit バイナリができあがります。build ディレクトリは中間ファイルが入っているだけですので、消してもかまいません。

ヘッダファイルは共通ですので、c:\usr\local\boost_1_46_1 をインクルードパスに指定しておけば、32bit と 64bit 両方から利用できます。

以上自分用のメモもかねてまとめてみました。