Go言語のメモ

「基礎からわかるGo言語」を読んだ. 2012年に発行された本なので,Goのバージョンがちょっと古い(Go 1.0.3)が,構文や考え方は大きく変わらないと思う. 今後,Go言語を使うことになるかもしれないので,気になったところをメモしておく. インスタンスの作成と初期化: インスタンスの作成方法には,下のコード例のように,いくつかの選択肢がある. 特に気を付けないといけないのは,Go言語にもポインタの概念があるので, ポインタと実体のどちらが生成されるのかという点である. また,インスタンス作成時に,構造体の要素に対する初期値を明示しなかった場合には, その要素にはゼロ値が割り当てられる点にも注意する. 例外として,スライス,チャネルおよびマップは参照型なので,newの代わりに,makeを使う. var x T // T型 y := T{ } // T型 z := &T{ } // *T型 w := new(T) // *T型 ブランクフィールド: 構造体の定義において,_ byteのように名前のない要素を定義すると,パディングを実現できる. インターフェースとnil: インターフェースに,T型の値xを代入すると,内部では<T,x>のように型と値が組になって格納される. これに起因して,インターフェース型の値pがnilかどうかをチェックするときは, 単純にnilと比較するのではなく,reflect.ValueOf(p).IsNil()を使う. var p1 *int var p2 interface{} = p1 fmt.Println(p1 == nil) // true fmt.Println(p2 == nil) // false fmt.Println(reflect.ValueOf(p2).IsNil()) // true リカバリ: 配列の範囲を超えたインデクス参照などによって致命的なエラーが発生したとき,あるいはpanic関数を呼び出したとき,プログラムはパニック状態になる. パニック状態になると,関数実行は中断され,main関数までコールスタックを遡っていく. ただし,その途中で,defer文によって遅延指定された関数は実行される. deferにより遅延して呼び出しされた関数の中で,そのパニックに対処できた場合は, recovery組み込み関数によって,パニックによるコールスタックの連鎖を中断できる. lenとcap: スライスsは,配列へのポインタ,長さlen,および容量capを持つ. ここで,スライスsの部分要素を参照するためにv := s[2:4]とすると, vとsは同じ配列を参照することになる. コピーが欲しければ,明示的に,copy関数を使わなければならない. この辺りは,内部構造を考慮しながら,コーディングしたほうが良い. チャネルの利用例: Goでは,スレッド間のデータ共有を実現するにあたって, 共有メモリではなく,チャネルという概念を導入している. チャネルは,スレッド間で任意のデータをアトミックに送受信するFIFO構造の通信機構である. チャネルを上手に使うと,同期,ミューテックス(セマフォ),およびデータ共有を実現できる. 例えば,同期であれば,ワーカスレッドがタスクの終了と同時にチャネルに何らかのデータを書き込み, マスタスレッドがチャネルを監視するという実装になる. ミューテックスであれば,大きさ1のチャネルを作り, 複数のスレッドからそのデータを取り合う,といった実装になる. データ共有であれば,同じく大きさ1のチャネルを作り, データの取り出しに成功したスレッドが,そのデータを更新し, 再度チャネルに書き込むという実装になる. select文 複数のチャネルから値を受信するとき,switch文に似た構文をもつselect文を使うことで, 受信可能なチャネルを選択できる.

January 21, 2017

2016年総括

例年どおり今年一年を振り返ってみることにした. 研究生活,アルバイト,趣味などを,項目ごとに思い出してまとめておく. 今年で,学生生活が終わることになる. ただ,修論と論文誌が残っているので, 年が開けても忙しくなりそう. 来年4月からは,関東に引っ越すことになった. UFJ,宝塚,通天閣にまだ行ってないので,関西にいる間に一度は行っておきたいところ. 研究 今年は,2つの国際会議で発表をした. 1つ目は,ギリシャで開催された会議である. 具体的には,ギリシャ・クレタ島の北部に位置する街イラクリオンで開催されたPDP2016である. これは,研究室に所属してから,初めての海外発表だった. 自分の発表は,会議全体からみて後半のほうだったと思う. 15分くらい拙い英語で発表をした. ただ,時間の都合で質疑応答が省略されたため,ちゃんと伝わったかどうかわからない. 移動の合間にクノッソス遺跡,パルテノン神殿,アテネ国立考古学博物館,ゼウス神殿を観光して周った. 2つ目は,11月にソルトレイクシティで開催された会議SC16である. ワークショップで発表した. 今回は,質問やコメントが3件あったが,ちゃんと答えられなかった. 言いたいことがあっても,なかなか英語が出てこなかった. 観光の時間はあまりなかったが,街の中心部にあるテンプルスクエアでオルガンリサイタルを聴くことができた. 復路で,ソルトレイクシティ発ロサンゼルス行きの飛行機がエンジントラブルか何かで遅れてしまうトラブルがあった. 他には,松本市で開催されたSWoPP2016で発表した. 後輩と一緒に参加して,発表をした. さらに,先輩が表彰受賞のために参加していて,一緒に懇親会で話をした. 2/15-22 PDP2016@ギリシャ 8/8-11 SWoPP2016@松本 9/12-13 旅行@金沢 10/5 GPU Japan@東京 10/5-7 OpenMPCon,IWOMP@奈良 11/13-19 SC16@ソルトレイクシティ アルバイト 3年くらいお世話になっている梅田の会社で,引き続きアルバイトとして,仕事をしていた. 今年は,サービスそのものの開発の他に,周辺ツールの整備をしていた. まず,サムネイル画像などを配信するためのCDN(Contents Delivery Network)を構築した. Nginxとそのモジュールで画像処理を行い,Amazon CloudFrontで配信した. 次に,Elasticsearchで各種ログを収集する環境を整えた. Amazon RDS,PHP,Nginxなどのログを収集・検索できるようになった. 最後に,cronで管理していたジョブをRundeckで管理するよう置き換えた. ジョブの実行ログをAmazon S3に,プロジェクトの設定をAmazon RDSに,それぞれ格納することで, 冗長構成になっている. アイドル しゃちほこ,アプガを中心に,いくつかのライブに参戦した. しゃちほこメンバが髪色を変えてみたり,干され気味の曲をセトリに取り入れてみたり,と満足度が高かった. アプガは,初の武道館ライブをやった.最後の挨拶によると,どうやら2期メンバを募集するらしい. 1/3 アプガ@梅田 5/21-22 しゃちほこ@幕張 7/17 アプガ@天満 7/29 Edge Dub Monkeyz@難波 8/3 しゃちほこ@名古屋 9/10 しゃちほこ@長崎 9/11 しゃちほこ@福岡 10/28 しゃちほこ@難波 11/8 アプガ@東京 バイク ほぼ毎日乗っているので,徐々に不具合が出てきた. 順次,オイル,フィルター,タイヤ,バッテリ,スパークプラグ,チェーン,スプロケを交換した. 加えて,二輪用ETCを取り付けた. ...

December 31, 2016

RTX1200初期設定

自宅用にルータRTX1200を買ってきた 1. 中古で2万円弱だった. GUIで設定できるところはGUIで設定し,残りをCUIで設定した 2. 具体的には,PPPoEとフィルタをGUIで設定し,VPNとDDNSをCUIで設定した. 忘れないように,設定内容をまとめておく. なお,工場出荷状態への初期化は, 前面のmicroSD,USBおよびDOWNLOADのボタンをすべて押下しながら, 電源を入れることで行われる. 工場出荷状態では,LAN1ポートが192.168.100.1/24で初期化され,DHCPが有効になっているので, telnetですぐに接続できる. telnetの他にも,コンソールやhttpで接続できるので,適当に接続する. > show config ess=**:**:**:**:**:** MAC-Address=**:**:**:**:**:** login password encrypted * administrator password encrypted * # デフォルトゲートウェイ ip route default gateway pp 1 # LAN1ポートのIPアドレス ip lan1 address 192.168.100.1/24 # ARPの代理応答 ip lan1 proxyarp on # フィルタ ip lan1 secure filter in 100000 ... # PPPoE pp select 1 description pp PRV/PPPoE/0:*** pp keepalive interval 30 retry-interval=30 count=12 pp always-on on # LAN2ポートを使う pppoe use lan2 pppoe auto disconnect off pp auth accept pap chap # PPPoE接続時のID,パスワード pp auth myname ****@**** **** ppp lcp mru on 1454 ppp ipcp ipaddress on ppp ipcp msext on ppp ccp type none ip pp secure filter in 200003 ... ip pp secure filter out 200013 ... ip pp nat descriptor 1000 # DDNS, netvolante netvolante-dns use pp server=1 auto netvolante-dns hostname host pp server=1 ****.aa0.netvolante.jp pp enable 1 # VPN pp select anonymous pp name vpn pp bind tunnel1 # PPP認証方式 pp auth request mschap-v2 # VPN接続ユーザ,パスワード pp auth username **** **** ppp ipcp ipaddress on ppp ipcp msext on ip pp remote address pool dhcp ip pp mtu 1258 pp enable anonymous tunnel select 1 tunnel encapsulation l2tp ipsec tunnel 1 ipsec sa policy 1 1 esp aes-cbc sha-hmac ipsec ike keepalive log 1 off ipsec ike keepalive use 1 off ipsec ike local address 1 192.168.100.1 # NATトラバーサル ipsec ike nat-traversal 1 on # 認証鍵,pre-shared key ipsec ike pre-shared-key 1 text **** ipsec ike remote address 1 any l2tp tunnel auth off l2tp tunnel disconnect time off l2tp keepalive use on ip tunnel tcp mss limit auto tunnel enable 1 # フィルタ ip filter 100000 reject * * udp,tcp 135 * (略) # NAT nat descriptor type 1000 masquerade nat descriptor masquerade static 1000 101 192.168.100.1 esp nat descriptor masquerade static 1000 102 192.168.100.1 udp 500 nat descriptor masquerade static 1000 104 192.168.100.1 udp 4500 ipsec auto refresh on ipsec transport 1 1 udp 1701 dhcp service server dhcp server rfc2131 compliant except remain-silent dhcp scope 1 192.168.100.2-192.168.100.191/24 # DHCP dns server pp 1 dns server select 500001 pp 1 any . restrict pp 1 dns private address spoof on snmp sysname yamaha-rtx1200-************ l2tp service on statistics cpu on statistics memory on statistics traffic on 参考 RTX1200 ↩︎ ...

December 17, 2016

Ansibleのメモ

最近,Ansibleを使うようになった.ちょうどAnsibleの解説本「Ansible完全読本」が,Kindle Unlimitedで公開されていたので読んでみた.インストール方法や使い方は省いて,今後ハマりそうな点だけをメモしておく. 設定ファイルは,YAML形式に準拠して記述する. 配列や連想配列を扱う際は,基本的に一行に一要素を記述する. 配列は- ,連想配列はkey: を接頭辞として,要素をその後ろに続けて書く. 空白文字が入っていないと文法エラーになるので,注意する. 例外として,=を使って,連想配列を定義できるが,文法がバラバラになってしまうので,使わない方が良い. 設定ファイルを編集し,その後デーモンを再起動したい場合は,Handlerを使う. Hanlderによって,デーモンが複数回再起動することを防げる. サーバに依存する値を設定ファイルに埋め込みたい場合は,Jinja2モジュールを利用する. このとき,その設定ファイルの名前に,nginx.conf.j2のように,.j2を付与する. 設定ファイルがAnsibleによって編集されたことを明示するために,設定ファイルの先頭にansible_managedをコメントとして,追加しておくと良い. これは,日付などに置換される. 設定ファイルを編集する際に,backup: trueとしておくと,バックアップファイルを作成できる. また,validate: ...としておくと,設定ファイルの文法エラーによるデーモンの起動失敗を未然に防げる. サーバの一覧は,Inventoryファイルとして管理する. Inventoryファイルには,静的Inventoryファイルと動的Inventoryファイルがあり, ファイルに実行権限が付与されているか否かによって解釈が決定する. 静的Inventoryファイルには,ホスト名をテキストで列挙する. 一方,動的Inventoryファイルはスクリプトとして記述し,実行時にホスト名を決定する. また,タスクによって,柔軟にInventoryを操作することもできる. これは,OpenStackのAPIを叩いて新規VMを作成,その後VMを初期化したい場合などに有用である. ansible-playbookコマンドは,Playbookに明示されたタスクに先立って,暗黙的にsetupタスクを実行する. setupタスクは,OSの種類やホスト名などFactと呼ばれるサーバの情報する. 対象サーバがOpenStackやAWS EC2によって管理されている場合には,Factに付加情報を追加できる. Version2以降では,Taskの一層外側にBlockという概念があり, Blockごとにtry,catchおよびfinaly処理のような例外処理を記述できる. さらに,Blockの外側にRoleという概念がある. 基本的には,サービスごとに独立してRoleを管理するのが良い. また,Roleを集めたAnsible Galaxyと呼ばれるリポジトリがある. 共通する処理を繰り返す場合は,with_itemsなどのwith*命令を利用する. ただ,with*命令は,種類が多いので,その都度検索するのが良いかもしれない. 1つサーバでだけ実行したい処理やローカル実行したい処理には,例外的に,run_onceや local_actionを利用する. SSHの同時接続数は,forksオプションによって設定する(デフォルトは5). Playbookは,step実行や特定tas実行を組み合わせて開発する. もし,既存のモジュールで不十分であれば,Pythonによってモジュールを自作できる. ディレクトリ構造 サービスごとにRoleを作っていき,site.ymlから呼び出すという構成が良い. ディレクトリ構造が複雑になるので,テンプレートをダウンロードすると良いかもしれない. site.yml # Playbookファイル hosts # Inventoryファイル roles/ role_name/ # Role名 tasks/ main.yml # Roleを構成するタスク handlers/ main.yml # ハンドラ vars/ main.yml # 上書きしない変数 defaults/ main.yml # 上書きする変数 meta/ main.yml # Roleの依存関係 files/ index.html # Copyで転送するファイル templates/ nginx.conf.j2 # Jinja2モジュールのテンプレート群

December 12, 2016

NUMAポリシー

NUMA環境で,スレッドやメモリの配置を明示的に指示する方法を調べたので,メモしておく. 1つの筐体に複数のマルチコアCPUを搭載する環境では,メモリはCPUごとに接続される. このような環境では, バスを介して直接つながったメモリ(ローカルメモリ)とCPUの間で,高速にデータを転送できる. 一方,直接つながっていないメモリ(リモートメモリ)にデータを転送するためには, QPI(QuickPath Interconnect)などのインタコネクトを介して, 他のCPUソケットを経由する必要がある. このようにメモリアクセスの仕組みが複数存在する環境は, NUMA(Nun Uniform Memory Access)と呼ばれる. NUMA環境で,マルチスレッドプログラムをチューイングするためには, スレッドをどのコアに割り当てるか,データをどのメモリに配置するかが重要になる. これらの制御は,numactlコマンドあるいはlibnumaライブラリによって実現できる. numactlによる制御 ソースコードを修正できない状況(あるいは面倒くさい状況)では, numactlコマンドを使って,アフィニティを設定する. --cpubind=<nodemask>オプションでスレッドをどのノードで実行するか指示し, --membind=<nodemask>オプションでデータをどのノードのメモリに配置するかを指示する. <nodemask>には,--membind=0,1のようにノード番号をカンマ区切りで記述する. 他にも, 優先してメモリを割り当てるノードを指示する--preferred=<nodenumber>オプションや 複数のノードにインタリーブでメモリを割り当てる--interleave=<nodemask>オプションがある. ノード番号などハードウェア情報は,--hardwareオプションで確認できる. また,プロセスに割り当てられたポリシーを確認するには,--showオプションを使う. # スレッドをノード0,データをノード0および1に配置 $ numactl --cpubind=0 --membind=0,1 ./a.out # メモリをインタリーブに配置し,numactl --showで確認 $ numactl --interleave=all numactl --show libnumaによる制御 ソースコードを修正できる状況では,libnumaを使う. numactlはプログラム全体のメモリ割付けを制御するが, libnumaは個々のメモリ領域を個別に制御する. libnumaを利用するには,コードにnuma.hをヘッダを追加し, 共有ライブラリをリンクする(-lnuma). ノード番号の集合<nodemask>は,nodemask_t型変数に格納する. メモリの確保では,どのようにメモリを確保するのかに従って, 適切なnuma_alloc_*ファミリの関数を利用する. メモリの解放には,共通してnuma_free関数を利用する. さらに,numa_run_on_nodeあるいはnuma_run_on_node_mask関数を使うことで, スレッドをどのノードで実行するかを明示できる. nodemask_t m; // ノード番号の集合を格納する変数m nodemask_zero(&m); // mを初期化 nodemask_set(&m, 2); // ノード番号2を有効に nodemask_clr(&m, 2); // ノード番号2を無効に nodemask_all_nodes(&m); // すべてのノードを有効に nodemask_no_nodes(&m); // 空集合に nodemask_isset(&m, 2); // ノード番号2がセットされていれば真 size_t s = 4 * 1024; // データサイズ4KB // 2番目のノードに確保 void *mem1 = numa_alloc_onnode(s, 2); // すべてのノードにインタリーブに確保 void *mem2 = numa_alloc_interleaaved(s); // mで示されたノードにインタリーブに確保 void *mem3 = numa_alloc_interleaaved_subset(s, m); // ローカルメモリに確保 void *mem4 = numa_alloc_local(s); // メモリ解放 numa_free(mem1,s); numa_free(mem2,s); numa_free(mem3,s); numa_free(mem4,s); // 現在のスレッドをノード1で実行 numa_run_on_node(1); // 現在のスレッドをmに含まれるどこかのノードで実行 nodemask_zero(&m); nodemask_set(&m,1); nodemask_set(&m,2); numa_run_on_node_mask(m); OpenMPによる制御 OpenMPを使ってマルチスレッドを実現している場合には,環境変数によってアフィニティを制御する. 制御方法は,コンパイラごとに異なり,例えば, PGIコンパイラであればMP_BINDおよびMP_BLISTを設定する. ...

October 7, 2016

移流方程式の数値解析

簡単のため1次元の波で考える 時刻\(t\)における座標 \(x\) の値を \(f(x-ut)\) とする 例えば,正弦波が速度\(u\)でx軸正方向に進むなら,\(f(x-ut) = sin(x-ut)\) この時,\(\frac{\partial f}{\partial t} + u \frac{\partial f}{\partial x} =0 \)が成り立つ.これが移流方程式 1次風上差分法 直線で近似する 数値解析なので,\(x\)は\(\dots,x_{i-1},x_i,x_{i+1},\dots\)のように離散的 \(x = x_i\)における\(f\)の近似を\(F_i^n(x)\)とする この手法は直線で近似するので,\(F_i^n(x)=a(x-x_i) + f_i^n, a = \frac{f_i^n - f_{i-1}^n}{\Delta x}\) ただし,\(f_i^n\)は\(x = x_i\)において時間ステップを\(n\)回進めた時の値 1時間ステップあたり時間は\(\Delta t\)だけ進む 時間ステップを進めると,$f_i^{n+1} = F_i^n(x_i-u\Delta t) = a(-u \Delta t) + f_i^n= - \frac{u \Delta t}{\Delta x}(f_i^n - f_{i-1}^n) + f_i^n$ プログラムでは,$K=u \frac{\Delta t}{\Delta x}$として以下を繰り返すだけ 図は,矩形波を与えたもの 風下もある for(i=1; i<99; i++) f_new[i] = -K * (f[i]-f[i-1]) + f[i]; for(i=1; i<99; i++) f[i] = f_new[i]; Lax Wendroff法 二次関数で近似する $F_i^n(x) = a(x-x_i)^2 + b(x-x_i) + c$で近似する $a,b,c$3つの定数が必要なので,$x$に適当に値を入れて, $F_i^n(x_{i-1}) = a \Delta x ^2 - b \Delta x + c = f_{i-1}^n$ $F_i^n(x_{i}) = c = f_{i-1}^n$ $F_i^n(x_{i+1}) = a \Delta x ^2 + b \Delta x + c = f_{i+1}^n$ ただし,$x_{i+1} - x_{i} = x_{i} - x_{i-1}=\Delta x$ これを解いて, $$ F_{i}^n(x) = a(x-x_i)^2 + b(x-x_i) + f_i^n, \\ a = \frac{f_{i+1}^n - 2f_{i}^n + f_{i-1}^n}{2\Delta x^2}, b = \frac{f_{i+1}^n - f_{i-1}^n}{2\Delta x} $$ 時間ステップを進めると, $$ f_i^{n+1} = F_i^n(x_i-u\Delta t) = f_i^n - \frac{u\Delta t}{2 \Delta x}(f_{i+1}^n - f_{i-1}^n) + \frac{(u\Delta t)^2}{2 \Delta x ^2}(f_{i+1}^n -2 f_i^n- f_{i-1}^n) $$ プログラムでは,風上差分と同様に$K=u \frac{\Delta t}{\Delta x}$として以下を繰り返すだけ for(i=1; i<99; i++) f_new[i] = f[i] - K*K*(f[i+1]-f[i-1])/2.0 + K*K*(f[i+1]-2*f[i]+f[i-1])/2.0; for(i=1; i<99; i++) f[i] = f_new[i]; ...

April 26, 2016

順伝播型ニューラルネットワークでMNISTの手書き数字認識

深層学習を勉強しようと思って,深層学習の本[1]を読んだ. さらに,MNISTデータセット[2]を使って,手書き数字認識プログラムを作った MNISTは,分類器を作る時のHello worldみたいなの 一番簡単な順伝播型ニューラルネットワーク(FFNN)を使う(他はよくわからん) 1章から4章あたりまで読めば実装に必要な情報が揃う 入力層,中間層,出力層の3層だけで構成 行列計算,データセットは既存のパッケージを使う 画像認識プログラムそれ自体は自分で実装する(caffe,TensorFlow等を使わない) この界隈ではPythonがスタンダードらしいので,それに従う ただ,Jupyter(IPython)は準備がめんどくさかったので保留 ソースコードは全部まとめて[3]に置いておく 順伝播型ニューラルネットワークの構築 構造が簡単な順伝播型ニューラルネットワーク(FFNN)を採用 多層パーセプトロンともいう 入力データを,多クラスに分類させる ネットワークは図のように構築する \(L\): 層の数.入力層,中間層,出力層の3層があればよい \(f^{(l)}(u)\): 第\(l\)層における活性化関数 \(f^{(l)}(u) = \frac{1}{1+e^{-u}} \): 出力層以外なら,ロジスティック関数を使う \(u_i^{(l)}\): 第\(l\)層の\(i\)番目のユニットにおける入力 \(z_{i}^{(l)}=f^{(l)}(u_i^{(l)})\): 第\(l\)層の\(i\)番目のユニットにおける出力 \(\mathbf{W}^{(l)}\): 第\(l-1\)層と第\(l\)層の間の重みを要素にもつ行列 各層の入出力を列ベクトルで表す \(\mathbf{u^{(l)}} = [u_0^{(l)} u_1^{(l)} \dots u_i^{(l)} \dots]^{T}\): 第\(l\)層のユニットへの入力を表す列ベクトル \(\mathbf{z^{(l)}} = [z_0^{(l)} z_1^{(l)} \dots z_i^{(l)} \dots]^{T}\): 第\(l\)層のユニットの出力を表す列ベクトル この時,順方向(入力層->中間層->出力層)の伝播は以下のように行列演算で書ける 入力を列ベクトル\(\mathbf{x}\)とすると,\(\mathbf{z}^{(0)} = \mathbf{x}\) 出力を列ベクトル\(\mathbf{y}\)とすると,\(\mathbf{y} = \mathbf{z}^{(L-1)}\) \(\mathbf{u^{(l+1)}} = \mathbf{W}^{(l+1)} \mathbf{z}^{(l)} + \mathbf{b}^{(l+1)}\) \(\mathbf{z^{(l+1)}} = f^{(l+1)}(\mathbf{u^{(l+1)}})\) ただし,\(\mathbf{b}^{(l)}\)は第\(l\)層のバイアス 分類するだけならここで終わり.\(\mathbf{y}\)が分類結果. 学習段階であれば,次に逆方向(出力層->中間層->入力層)の伝播を行う. \(\mathbf{d}\): \(\mathbf{x}\)の正解データ \(\mathbf{\Delta}^{(L-1)} = \mathbf{z}^{(L-1)} - \mathbf{d}\) \(\mathbf{\Delta}^{(l)} = f^{(l)’} ( \mathbf{u^{(l)}} ) \odot \mathbf{W}^{(l+1)T} \mathbf{\Delta}^{(l+1)} \) \(\odot\): 行列の要素同士の積 \(f^{(l)’}(u)\): \(f^{(l)}(u)\)の導関数 \(\mathbf{\Delta}^{(l)}\)が求まれば,それをもとに重みとバイアスを更新する. ...

April 24, 2016

Macbook Air(13-inch, Mid2012)にdebian 8.0 jessieをインストール

Macbook Air(13-inch, Mid2012)にdebian 8.0 jessieをインストールするメモ. SDカードにインストール まず,インストール対象のSDカード以外に適当なメディア(/dev/diskX )を用意し, /dev/diskXにdebian 8.0 jessieのLive install imageを焼く. 焼けたら,commandキーを押しながら再起動して,/dev/diskXからdebianを起動する. $ diskutil unmount /dev/diskX $ dd if=debian-live-8.3.0-amd64-lxde-desktop.iso of=/dev/diskX 次に,SDカード(/dev/diskY)に2つのパーティションを作る. パーティション方式はGUIDパーティションテーブル(GPT)を使う. 1つ目のパーティションをFAT32,2つ目のパーティションをext4等でフォーマットする. $ diskutil list (略) /dev/diskY #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *7.8 GB diskY 1: Microsoft Basic Data EFI 1.0 GB diskYs1 2: Microsoft Basic Data 6.7 GB diskYs2 フォーマットが終わり次第,1つめのパーティション(diskYs1)に,UEFIブートマネージャのrEFIndをインストールする. $ mount -t msdoc /dev/diskYs1 /Volumes/EFI $ ./refind-install --ownhfs /Volumes/EFI --alldrivers $ cp /Volumes/EFI/System/Library/CoreServices/refind_x64.efi \ /Volumes/EFI/System/Library/CoreServices/boot.efi 最後に,2つ目のパーティション(diskYs2)に,rootfsを構築していく. ...

March 15, 2016

2015年総括

明けましておめでとうございます. 今年もよろしくお願いします. 去年を出来事を簡単にまとめてみます. 研究 M1になった. 卒論や修論など明確な〆切がないので,あまり焦りやプレッシャーを感じず, のんびり過ごしていた. 研究内容を簡単に紹介すると,CPU向け逐次コードをGPU向けコードへ自動変換するというものである. 10月くらいまでは,出力すべきGPU向けコードをチューニングしていた. 以後,自動変換ブログラムの実装に取り掛かっている. B4の頃よりも発表や聴講の機会は増えた. 1/26-1/27 ACSI2015@つくば 2/20 卒論発表会@研究科 3/2-2/3 HPC148@別府 5/19-20 HPCS2015@東京 8/4-8/6 SWoPP2015@別府 9/18 GTCJapan2015@東京 12/16-12/17 HPC152@札幌 バイト 去年と同じ職場でアルバイトと外注の仕事をしていた. しゃちほこ 去年に引き続き,チームしゃちほこのライブやイベントに参加していた. 今年は多くのメンバーが卒業するので,活動がより活発になるかもしれない. 1/3 鯱詣@愛知県体育館:確かプロレスをイメージしたポスタと円形ステージだった気がする.乙女英語verをお披露目. 3/28 『天才バカボン』発売記念フリーなイベント@札幌ファクトリー:ミルクス,たこ虹もいた.ライブ前にGTR(ラジオ)公開収録. 4/18 『天才バカボン』発売記念フリーなイベント@大阪城野外音楽堂:4月にも関わらず,きつい日差し.ぽんさんは足をけがしてて車いす.いけいけハリウッドを初披露. 5/9-5/10 幕張HOLLYWOOD@幕張メッセ:爆発の演出でビビる.鯱本を購入. 5/17 『天才バカボン』発売記念フリーなイベント@名古屋オアシス21:まだまだ新曲についていけない. 7/14 「鯱本」1万冊突破記念「行くぜ、しゃちサマ」トークイベント@梅田ブルク7:咲良さん,坂本さん,店長と編集の津田くん.案の定ふたりとも読んでない. 7/26 CBCラジオ夏祭り2015@名古屋久屋広場:アンセム推しすぎな気がする.Silent Sirenも見た. 8/28 しゃちサマ@蒲郡ラグーナテンボス:ほのかが永遠のトリニティーをカバー.終盤は花火が上がってた.しゃちほこーるが公開されたのもこの辺. 9/30 ホールツアー2015さきどりハロウィンパーティー@名古屋国際会議場:ぽんさんとなおちゃん以外の4人は色を変えて登場.魔法にかけられた設定. 10/17 ホールツアー2015さきどりハロウィンパーティー@長崎チトセピアホール:3人で運転を交代しつつ車で移動.コアなひとが多くて楽しい. 10/18 第61回名古屋まつり@名古屋久屋広場:長崎からそのまま移動.5曲くらいだったけど楽しい. 10/29 「ええじゃないか」発売を記念したイベント@梅田タワレコ:付き添い. 11/15 「ええじゃないか」特典会@ポートメッセ名古屋:秋本さん誕生日. 12/10 年末大感謝祭ソロライブ@名古屋ELL:ほのテルで銀河鉄道999をカバー.弱虫ペダル推しまくってた. アプガ 体力があるグループで,2時間くらいノンストップで歌とダンスで盛り上がる. 10/16 全国47都道府県ツアー@徳島club GRINDHOUSE:初めて見に行った. 11/29 ハイスパートRAVE FESTIVAL@京都FANJ:2時間ワントラックのノンストップライブ. バイク オイル,ブレーキフルード,スロットルワイヤを交換した. あとは,タイヤとグリップヒーターをなんとかしたい. 秋頃に大自二をとった. ...

January 3, 2016

省エネサーバを作ってみた

さくらVPSの1Gプランのインスタンスをウェブサーバやストレージとして動かしているが,いくつか不満なところがある. ストレージが自宅とVPSでバラバラ どうせ自宅でPCつけっぱなし そこで,自宅にサーバを置くことにした. 条件はありきたりだが,こんな感じ. PCIスロットあり PCIeは特に使わないが,あったらよい 静音(ファンレス,スピンレス) 安い(全部で上限4万) 省電力 SATA2つ以上 ちょっと調べてみて,DN2820FYKH(15,000円)というNUC(Next Unit of Computing)を使おうと思った. NUC本体に加えて,メモリとストレージだけ買ってくれば完成するので簡単だし, 値段,静音性,消費電力の条件を満たしている. 注意点は, メモリには1.35Vの省電力メモリ(DDR3L 1333/1600)を使うこと, 最大メモリ容量は8GBであること, ドライブは2.5インチであることくらい. あと,SATAのスロットは1つだけで,PCIeはひとつもないので拡張は全く出来ない. よく考えてみると拡張出来ないのは痛いから,多少高くつくが部品ごとバラバラに買うことにした. CentOS x86_64 サーバー構築・運用 - System House ACT 公式ブログや 静音化:SST-ML05Bケースに、玄人志向のACアダプタKRPW-AC120Wを載せる | Atom Fusion に同じマザーボードを使って構成した人がいるので参考にした. GA-J1900N-D3Vは少し古くてSATA 3.0がなくメモリの周波数もちょっと気になるが,PCIスロットがありNICが2つありということで,妥協した. 実際に動かしてみると,HDDのシーク音がうるさいのが気になった. 他のHDDと比べてもうるさいので,選択を間違ったかハズレを引いたんだろう. マザーボード GA-J1900N-D3V 13,000円 Mini ITX ATX電源 PCIスロットあり Mini PCI Expressスロットあり(PCIe 2.0相当) Celeron Quad-Core J1900(Bay Trail-D,2.0GHz,4コア,TDP 10W) DDR3/DDR3L-1333(PC3-10600) 2ソケット(最大8GB,1.5Vでも1.35Vでもどちらでもok(ここは日本語,英語マニュアル間で差があるもよう)) SATA 2.0(3Gbps)が2本 SATA 3.0(6Gbps)はなし GbEが2つ ケース SST-ML05B 6,000円 Mini ITX 2.0インチドライブを4台 3.5インチドライブ,2.5インチドライブ,120mmファンのどれかとして使える汎用的なシャドウベイを1台 SFX電源 ケースには8センチファンが2個つけられる 電源 KRPW-AC120W(KRPW-TX300W/90+) 6,700円 ATXとSFXに対応 メモリ ADDS1600W4G11-R [SODIMM DDR3L PC3L-12800 4GB] 3,500円 4GB 1.35V ディスク WD20EZRX 8,000円 3.5インチ

July 20, 2015

Codeforces Round 308 (Div.2), ARC040

ちょっと競技プロをやってみた. Codeforces #308 (Div.2) Codeforcesに初参加. 結局A-Eの5問中,Aしか解けなかった. Aは,実装するだけという感じだったので,そんなに時間がかからず解けた. Bは,ヒストグラムを作れば解けたと思うが,それに気づくのが遅かった. Cは,4番目のpretestで失敗. D,Eは手を付けてない. それと,pretestに失敗した時は,「My contest submissions」から テストケースの詳細が見れるのを知らなかった. ARC040 4問中3問解けた. 問題DはDPかなんかで計算量下げるんだろうなと思ったが, 全探索以外の手法が思いつかず終了. 精進します.

June 15, 2015

5五将棋 AI制作のメモ

本将棋のサブセットである「5五将棋」のAIを ちょろちょろ書いている, 気づいたことをメモしておく. データ構造 それぞれの駒をビットボードで管理している. 例えば先手の歩が7番目の位置に存在すれば,bitboard[B_PAWN] = 0x40 のように表す. 飛車および角の効きはAVX2の_pext_u32命令を使い導出する[5]. 探索方針 基本はアルファベータ法で探索する. それに加えて,合法手をソーティングしつつ,反復深化させる. また,同一局面が現れた場合は,置換表を用いてalpha-betaのウィンドウ幅を狭める. Null-Window(PVS)探索も試してみたが,対して速くならなかった.むしろ遅い場合もある. 多分ソーティング方法が悪い. 評価関数 単純に駒の損得だけで評価している. 改善が必須. USI(Universal Shogi Interface)プロトコル 将棋GUIソフト[8]とAIを接続するプロトコルの1つがUSIである[6,7]. AIは,GUIソフトから局面や持ち時間を受け取り,決定した指し手を返す. とりあえず対応させた. OpenMPによる並列化 探索はOpenMPを使って並列化している. 与えられた局面の合法手をそれぞれ並列に探索する. 出来るだけ静的にリンクしたいので,ちょっと調べてみた. visual c++ 構成プロパティ - C/C++ - 言語 - OpenMPのサポートを「はい」にする 構成プロパティ - C/C++ - コード生成 - ランタイムライブラリを「マルチスレッド(/MT)」にする VCOMP{90,100,110,120}.dllに依存する VCOMP{90,100,110,120}.dllは,/MTを設定しても動的にリンクされるため, どこかで配布されているものを使ってみようかな[1,2]. gcc libcompに依存するが,静的リンクする方法はあるみたい[4]. intel compiler libiomp5m.libを静的リンクすることができるらしい[2]. 静的リンクは非推奨らしいが,-openmp-link staticオプションを付けると良いみたい(icpc -openmp -openmp-link static hello.cpp)[3]. 参考 [1] Stack Overflow, Is there a way to load in omp.h at compile time, therefore a machine never needs to fetch it at run time? [2] Visual Studio UserVoice site, Statically link openmp (vcomp*.dll) [3] Intel® C++ Compiler XE 13.1 User and Reference Guide - Using the OpenMP* Libraries [4] Stack Overflow, How to link libgomp statically when linking other libraries dynamically? [5] インテル C++ コンパイラー 14.0 ユーザー・リファレンス・ガイド - _pext_u32/64 [6] 将棋所 [7] The Universal Shogi Interface [8] プチ将棋の使い方

May 29, 2015

どうぶつしょうぎの完全解析

(7/10追記) 完全解析の結果を利用するAIをdobutsu-shogi.jar(17MB)に置いておきます.対戦してみてください. 今更な感じですが,どうぶつしょうぎの完全解析をしてみました. やり方はすでに公開されてますので,不明点はそちらを参考にしてください(「どうぶつしょうぎの完全解析」, 田中哲朗). 私の実装もそちらを参考にしています. 解析のゴールは,後手の場合は78手で確実に勝ち,先手の場合は出来るだけ負けにくい手(負けまでの手数が最も長い手)を指すAIを完成させることです. 以下2つのステップにより,完全解析を目指します. 1つ目は,初期局面から開始し,ありうる全ての局面を展開することです. やり方は単純で,ある局面の合法手を全て展開していくだけです. 計算時間は数十分程度ですか,メモリを多く使います. そこで,駒を左右入れ替えて配置し直しても同じ局面と見なし(全ての駒の動きは左右対称であるから),局面数を減らします. 解析結果all-stateは,今後の利用のためソーティングしておくと良いです. all-stateは,1局面64bit x 246,803,167 = 1.9 GBくらいになります. コードはこちら. // // q: 未解析局面のキュー,初期値は初期局面のみが格納されたキュー // h: 解析済み局面のマップ,初期値は空マップ // all_state: 解析済み局面のベクタ,初期値は空ベクタ // while(!q.empty()) { if (i>=MAX_BOARD_NUM) { break; } b = q.front(); q.pop_front(); iter = h.find(b); if (iter == h.end()) { all_state.push_back(b); h.insert(b); i++; // 終わった盤面からは解析しない if (!is_win_state(b) && !is_lose_state(b)) { next_boards.clear(); get_next_board(next_boards, b); n = next_boards.size(); for (j=0; j<n; j++) { // ちゃんと正規化して,手番を合わせて保存 b = get_reverse(next_boards[j]); b = regulate(b); q.push_back(b); } } } } 2つ目は,全ての局面all-stateを勝ち/負け/引き分けのどれかに分類することです. まず,勝ち確定局面(次の一手で確実に相手のライオンが取れる),負け確定局面(勝ち局面ではなく,相手のライオンが自陣に位置しトライが決まった),それ以外の局面の3種類に分類します. あとは,以下の方針で,勝ち局面/負け局面を解析していきます. どちらも増えなくなれば,残りを引き分け局面とし,プログラムを終了します. 次の局面の内少なくとも一つが負け局面であれば,その局面は勝ち局面 次の局面が負け局面に移行するように打てば勝てる 次の局面が全て勝ち局面であれば,その局面は負け局面 どのような手を打っても,次の局面は勝ち確定だから相手が勝つことになる コードはこちら. for(;;) { unsigned int win_add_num = 0; unsigned int lose_add_num = 0; for (size_t i=0; i<STATE_NUM; i++) { board b = all_state[i]; if (judge[i] == UNKNOWN) { // 一手先の局面から現在の局面の勝敗を判定 unsigned char winorlose = get_winorlose(b, all_state, judge); if (winorlose == WIN) { judge[i] = WIN; judge_count[i] = iter_num; win_add_num++; } else if(winorlose == LOSE) { judge[i] = LOSE; judge_count[i] = iter_num; lose_add_num++; } } } // これ以上勝ち確定も負け局面も増えなければ, // 残りは全て引き分け局面 if (win_add_num == 0 && lose_add_num == 0) { break; } } 結果として,カンペキな計算で作られたこのAI?は,後手の場合確実に勝てるものになりました. 先手の場合でも,ほとんど負けないでしょう. ...

May 28, 2015

4clojureのススメ

clojureの学習サイトの1つに,4clojureがある. 難易度がElementary,Easy,Medium,Hardと分かれているので, これから始める人にちょうど良いかなと. 無限遅延シーケンスとかはclojure独自なものだし,普段のコーディングで あんまり意識しないので面白い. とりあえず先ほど全完してきた.

May 16, 2015

2014年総括

最近記事を書いてないからちょっとまとめて書いておく. 覚えている限りで書いてるから忘れてるものもたくさんありそう. こうみるとただただ遊んでるだけの時間が長かった. しゃちほこ 3/29 ZEPP FINAL! 2014@zeppなんば 4/19 ZEPP FINAL! 2014@zepp名古屋 4/26 いいくらし発売記念Free Event Tour@京都新風館 8/28 しゃちサマ@武道館 途中新幹線使っちゃったような ほのかがとんでた,たんま 11/02 カラオケワンダーランドツアー@浜松アクトシティホール 近鉄,名鉄,JRを組み合わせて行った さわやか 11/24 シャンプーハット発売記念FreeなLive@千里セルシー 握手を2回 11/30 カラオケワンダーランドツアー@大阪オリックス劇場 車で連れてってもらった 3階席 いいじゃないの〜,出会っちゃったやで−(ほのか),アンパンマン,スベッカム(ゆずき) 研究室 無事希望の研究室へ. 1月中にポスタ提出,2月に卒論発表.これから忙しくなるぞ. 院試 あれ,まだ過去問作ってないような… バイク 院試前後で,免許を取得. 近くのバイク屋に探してもらってたが結局別のところで買うことになった. メール,電話でかなり親身に探してくれた. lisp これに関してはあんまり進展してないような… ガンバ 残ればいいくらいのつもりだっけど三冠やっちゃったもんな 3/1 ガンバ 0-1 浦和@万博 槙野に混戦から失点 3/19 ガンバ 2-0 神戸@万博 リンス初ゴール 4/12 セレッソ 2-2 ガンバ@長居 フォルラン二発やられるも阿部ちゃんがやり返す 4/29 ガンバ 1-2 柏@万博 田中順也のコントロールシュートに,最後フリーキック 15位 千中で寄せ鍋 8/2 ガンバ 2-0 マリノス@万博 院試筆記が終わって直ぐに行った. 遠藤-パトのホットライン 2点目も遠藤 8/16 ガンバ 0-1 名古屋@万博 5連勝が途切れた 審判がちょっとあれだった ファールスローもとらないなんて... 10/09 ガンバ 3-1 川崎@万博 11/29 ガンバ 3-1 神戸@万博 バイト 普通のバイトをしつつ、外注で2件仕事をもらってた 片方はまだ終わってないや ...

January 2, 2015

clojureのクラスリロード

前回もクラスローダのあたりを書いたがあんまりしっくりしないのでもうちょっと調べてみる. JavaのClassLoaderの仕組みが分かっていなかった. まずStack OverflowのHow does clojure class reloading work?から. 質問 私はclojureでクラスのリロードの仕組みについてコードやドキュメントを 調べてきました. 多くのwebサイト,例えばhttp://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html によると,クラスのロードは本質的に どんなデータ構造であれバイト列を得ることでそれを defineClassによりclassClassのインスタンスに変換し, resolveClassによりそのclassをresolve(link)することであるということでした. (defineClassは暗黙的にresolveClassを呼んでいるのでしょうか?) どんなclassloaderでもclassのリンクは一度だけに限定されています. もし既存のclassへリンクしようとした場合でも何も行われないようです. これでは新しいclassインスタンスをリンクできないという問題があり, classをリロードする際は毎度classloaderのインスタンスを作る必要があります. clojureに注目してみると,clojureには複数のクラス定義方法があります. 匿名クラス: reify proxy 名前付きクラス: deftype defrecord(内部ではdeftypeを使っている) gen-class これらに関するコードは最終的にclojure/src/jvm/clojure/lang/DynamicClassLoader.java へたどり着きます. DynamicClassLoader/defineClassではclassインスタンスを作り,キャッシュしておきます. クラスをロードし利用する場合はforNameを呼び,またそれはDynamicClassLoader/findClassを 呼びます. DynamicClassLoader/findClassは,キャッシュを検索しその後基底クラスを検索します. (通常のclassloaderでは逆に基底クラスを先に検索するようです.) 混乱の元になっているのは, forNameはclassをリンクする前に返す(returnする)とドキュメントにある これは既存のDynamicClassLoaderではclassのリロードが行えない 代わりに新しくDynamicClassLoaderのインスタンスを作らねばならないがそのコードが見つからない ということです. proxyやreifyは匿名クラスなのでクラス名が異なっていても問題ありません. しかし,名前付きクラスの場合はそうはいきません. DynamicClassLoaderの仕組みを教えてください. 最終的にはjavacでコンパイルされた.classファイルをロード,リロードさせたいのです. 回答 以下全てが同じ技術を使っているわけではありません. proxy proxyマクロは基底クラスやインタフェースから名付けられたクラスを作ります. それぞれのメソッドはインスタンス内でclojureのfnとして扱われるため, マクロの内部が同じか否かに依らず, 同じインタフェースが継承される場合は同じproxyのクラスが使われます. 実際にクラスのリロードは行われません. reify reifyの場合は,メソッド本体が直接classの中にコンパイルされるため, proxyのトリックは使えません. 代わりに,formがコンパイルされる度に新たなクラスができるため, もし本体を編集してリロードしたとしても完全に新たなクラス(新しい名前)が作られます. これも実際のクラスのリロードは行われません. gen-class gen-classではクラス名を指定するため,proxyやreifyとは異なります. gen-classマクロは枠組み(spec)のみを持ち,メソッド本体は持ちません. つまりproxyと似て,clojureのfnを参照するということです. しかしproxyと違いクラス名が枠組み(spec)と結びつくため,本体を修正しリロード ということは出来ません. 従ってgen-classはAOTでのみ利用可能でJVMの再起動が必要です. deftypeとdefrecord これらでは実際に動的なクラスのリロードが行われます. そのクラスを含むコードをコンパイル場合やforNameが呼ばれた場合など クラス名を解決する必要があるときは,DynamicClassLoader/findClass が呼ばれます. ...

May 20, 2014

clojureバイトコードと名前空間のロード

clojureが*.cljをコンパイルしたときに,どのようなバイトコードが 生成されるのかを調べてみる. まずは,単純な例: (ns example.hello)から始めてみる. 気をつけること コンパイル単位は名前空間 名前空間ごとにクラスローダ"namespace__init.class"が作られる http://clojure.org/compilationに詳細あり コンパイル時は(コンパイル対象のclojureコード)ソースディレクトリをクラスパスに含める 実行時はコンパイルされたクラスファイルの他にclojure.jarをクラスパスに含める コンパイル leiningenを使わず,生のclojureでコンパイルしていく. 以下のように3つのクラスファイルが作られる hello__init.class hello$fn__4.class hello$loading__4958__auto__.class $ mkdir clojure-work ; cd clojure-work $ wget http://central.maven.org/maven2/org/clojure/clojure/1.6.0/clojure-1.6.0.jar $ mkdir -p src/example $ vim src/example/hello.clj (ns example.hello) $ mkdir classes $ tree . ├── classes ├── clojure-1.6.0.jar └── src └── example └── hello.clj $ java -cp ./src:./classes:clojure-1.6.0.jar clojure.main user=> (compile 'example.hello) $ tree classes classes └── example ├── hello$fn__4.class ├── hello__init.class └── hello$loading__4958__auto__.class ## もし,hello.cljにmain関数を定義したならば ## hello.classが作られるように:gen-classをつけコンパイルする. # $ java -cp clojure-1.6.0.jar:./classes example.hello マクロ展開 名前空間を作る(ns ’example.hello)は,マクロなので展開しておく. まず,macroexpandの結果. ...

May 15, 2014

Debianのlivecdの作り方

livecdの作り方が気になったのでやってみた. livecdを作っておくとデモとか楽になるかもしれない. 1. ツール群インストール # aptitude -y install xorriso live-build syslinux squashfs-tools 2. debootstrap 適当にworkディレクトリ(/livework)を切って,debootstrapで新しい環境作りをする. これで,/livework/chroot以下にbin, etc, varなどの構造が作られる. # mkdir ~/livework && cd ~/livework # debootstrap --arch=amd64 sid chroot 3. chroot chrootを使い,debootstrapで作った新環境に潜る. proc等をマウントし,カーネルイメージとlive-bootをインストールする. # chroot chroot # export HOME=/root # export LC_ALL=C # export PS1="(chroot) $PS1" # mount -t proc none /proc # mount -t sysfs none /sys # mount -t devpts none /dev/pts # aptitude -y install linux-image-amd64 live-boot # passwd # aptitude clean # rm -rf /tmp/* # umount /proc /sys /dev/pts # exit 4. isolinux ディレクトリbinaryを作って,vmlinuzとinitrdをchroot環境からコピーする. mksquashfsでchroot以下からファイルシステムを作成(圧縮)する. ただし,/bootだけは除く.(mount binary/live/filesystem.squashfs /media/hogeで確認できる) CDから起動する場合はsyslinuxを使うみたい. ...

April 7, 2014

Gentoo install on Virtualbox

Gentooをインストールしたことがなかったので, Gentooハンドブック通りにやってみる. 日本語版が更新されてないのがよく分かった. 環境 uname -a: Linux debian 3.13-1-amd64 #1 SMP Debian 3.13.7-1 (2014-03-25)x86_64 GNU/Linux Virtualbox 4.3.6 1. Gentoo Linuxのインストールについて シンプル,先進的なメタディストリビューション システム全体をスクラッチからでも,コンパイル済みからでも, 半分だけでもおk 2. 適切なインストールメディアの選択 http://mirrors.stuhome.net/gentoo/releases/x86/autobuilds/current-iso/install-x86-minimal-20140401.isoを使った GentooインストールCDは独立したGentoo環境を含むブート可能CD install-x86-minimal-<release>.iso ディスク容量が104MBしか使わない 必ずネットワーク上環境が必要 stage3 tarball 本マニュアルの対象 現在でもstage1, stage2は配布している ドキュメントもある 書き込んでブートする http://www.gentoo.org/main/en/mirrors.xmlから取ってくる releases/x86/autobuilds/current-iso パラメータを指定する 例えばgentooカーネルにカーネルパラメータdopcmciaを指定するなら, boot: gentoo dopcmciaみたいにする 普通に boot: gentooってやった すぐにキーボードを変更する. 22 JPにする 3. ネットワーク設定 勝手につながってたので飛ばす proxyの設定はこのタイミングで net-setup, pppoe-setup, pptpを使う net-setupが一般的 もし,カーネルモジュール(ドライバ)に不足があれば 手動でやる ls /lib/modules3.12.13-gentoo/kernel/drivers/net/ から見つけて modprode pcnet32とする 無線の場合はiwconfigでチェック iwconfig eth0 essid hogehogeman iwconfig eth0 key 1234hoehogeman 4. ディスクの準備 ブロックデバイス SCASI,SATAは/dev/sd*みたいに パーティション MBRなら 4つの基本パーティション それ以上なら論理パーティションとして partedでパーティション作り パーティションIDは指定するが, ファイルシステム自体は次で作成する parted /dev/sda (parted) print (parted) mklabel gpt # パーティションテーブルをGPTに (parted) rm 2 # いらんパーティションがあれば消す (parted) mkpart primary ext2 0 32mb # /boot (parted) mkpart primary linux-swap 32mb 544mb # swap (parted) mkpart primary btrfs 544mb -1s # / パーティションにbtrfs、ext*、ocfs2またはxfsファイル・システムを作成する場合は、ext4?? ファイルシステム作成 mkfs.ext2 /dev/sda1 mkfs.btrfs /dev/sda3 mkswap /dev/sda2 swapon /dev/sda2 マウント mkdir /mnt/gentoo mount /dev/sda3 /mnt/gentoo mkdir /mnt/gentoo/boot mount /dev/sda3 /mnt/gentoo/boot 5. Gentooインストールファイルをインストールする stage3-i686-20140401.tar.bz2を保存,解凍 cd /mnt/gentoo links http://www.gentoo.org/main/en/mirrors.xml tar xvf stage3-i686-20140401.tar.bz2 portageのインストール(/snapshotから) cd /mnt/gentoo/usr links http://www.gentoo.org/main/en/mirrors.xml tar xvf portage-latest.tar.bz2 /mnt/gentoo/etc/make.confls portageのコンパイル設定 /mnt/gentoo/usr/share/portage/config/make.conf.exampleを参考に /mnt/gentoo/etc/make.confを設定 6. Gentooベースシステムのインストール DNS情報のコピー cp /etc/resolv.conf /mnt/gentoo/etc chrootで新しい方に潜る http://d.hatena.ne.jp/tmatsuu/20101225/1293262061 潜ったら env-update #環境変数の変更?? source /etc/profile export PS1="(chroot) $PS1" portage更新 emerge –sync profileの確認?? eselect profile list USE変数の確認?? 第二部に詳細あり 7. カーネル設定 emerge gentoo-sources 別ttyでtail -f /mnt/gentoo/var/log/emerge-fetch.logとか usr/src/内に保存 emerge pciutilsして,lspciか chroot外で,lspciか lsmodをパクるか make menuconfig Processor type and features –> Processor family Device Drivers –> Generic Driver Options –> Maintain a devtmpfs filesystem to mount as /dev File systems –> Btrfs filesystem support File systems –> Partition Types Enable the block layer あたり注意 make -j3 CPU you selected does not support x86-64だったので, 64bit kernelを諦める make modules_install /lib/modulesあたりにインストール カーネルイメージを移動 cp arch/i386/boot/bzImage /boot/kernel-3.12.13-gentoo-r1 /etc/conf.d/modulesあたりでオートロードなモジュールを設定 8. システム設定 /etc/fstabを設定していく ここらでvimが欲しくなったので,emerge vim /etc/conf.d/hostname /etc/conf.d/net 9. システムログツール emerge syslog-ng; rc-update add syslog-ng default まあいいや emerge btrfs-progs もう,いらないか... 10. ブートローダを設定する もうgrub2だから英語の方を参考にする emerge sys-boot/grub grub2-install /dev/sda パーティションにbios_grubフラグがないとダメみたい this GPT partition label contains no BIOS boot partition;とか怒られる. (parted) set 1 bios_grub onでおk http://wiki.gentoo.org/wiki/GRUB2 grub2-mkconfig -o /boot/grub/grub.cfg /etc/default/grubか/etc/grub.dに書いてもいいけど 書かなくても勝手に探してくれる ファイルシステムを特定できないみたい grub2-probe / => btrfs grub2-probe /boot => unknown filesystem ext2が認識できないのはまずい 恐らくgrub2-installとかでやっちゃったんだと思う ハマる ここでBIOS boot partitionとBoot Partitionが必要なことに気づく… /bootだけフォーマットしなおす できた マウントしなおして潜る mount /dev/sda3 /mnt/gentoo/ mkfs.ext2 /dev/sda4 mount /dev/sda4 /mnt/gentoo/boot mount –rbind /dev /mnt/gentoo/dev mount -t proc none /mnt/gentoo/proc mount –rbind /sys /mnt/gentoo/sys chroot /mnt/gentoo /bin/bash * /etc/fstabを治す,カーネルをコピーしてくる * grub2をもっかいインストール grubからgentooを起動する rootのパスワードを設定忘れる 潜ってpasswd root

April 6, 2014

scheme REPLとガベージコレクション

REPL 普通のREPL. 相変わらずパイプで繋いでる. トップレベルにS式を打ち込む度に流し込んでやるとできた. 逆アセンブル (disasm ..)とかいう命令を追加した. こんな感じで逆アセンブルした結果を確認できる. >>(disasm (+ 1 2 3)) === code === 0 0x12000002 ;FRAME 1 0x0000003c ;15 2 0x25000002 ;CONSTNUM 3 0x0000000c ;3 4 0x13000002 ;ARGUMEMT 5 0x25000002 ;CONSTNUM 6 0x00000008 ;2 7 0x13000002 ;ARGUMEMT 8 0x25000002 ;CONSTNUM 9 0x00000004 ;1 10 0x13000002 ;ARGUMEMT 11 0x03000002 ;REFER_GLOBAL 12 0x094bf2f3 ;+ 13 0x15000002 ;APPLY 14 0x0000000c ;3 15 0x27000002 ;DISASM 16 0x00000002 ;HALT ガベージコレクション cheneyのcopy gcを実装して埋め込んだ. 同じ大きさのFrom空間とTo空間という二つの領域を確保しておいて, From空間にallocateしていく. From空間が満タンになれば,ルートオブジェクト(レジスタとかシンボルテーブルとか)から たどれるオブジェクトをすべてTo空間にコピーする. 全部のコピーが終われば,From空間とTo空間を交換する. 単純なアルゴリズムともいえるけど,ルートを忘れやすいので注意が必要. ヒープの効率が悪くなったり,保守的GCじゃないなどデメリットがある. まあヒープは現状問題ないだろうし,スタックやレジスタの要素がオブジェクトかプリミティブ かは判定できるのでexactなGCで問題ない. メリットは,フラグメンテーションが起こらない,キャッシュと相性がよいなど素晴らしい. ここまでは,copy gcの話. ...

March 7, 2014