9/30 (日)
デイデンチュツ祭り@江東区
ミャンマーの祭「デイデンチュツ祭り」(公式)が江東区の木場公園で開催されたので見てくる。
木場公園は都市緑化植物園と隣接して真ん中に川が流れている。 架橋でつながっている。
会場。
なんか何か食べてみるが、詳細はよくわからない。
今日見つけた変な建物
木羽公園から見えるルービックキューブが乗った建物。 木場パークビルというらしい。
9/28 (金)
[Prog] ibv_create_cq の引数 comp_vector の意味
InfiniBand Verbs で Completion Qqueue(CQ) を作る際に comp_vector
という引数がある。
この引数がどのような意味を持っているのかという話。
struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, void *cq_context, struct ibv_comp_channel *channel, int comp_vector);
引数 context
は /sys/class/infiniband/uverbs/uverbsN を open した時に作成されるデバイスとの連絡用のコンテキストなので疑いはない。
引数 cqe
はこの CQ の最大エントリ数を指定する。
これも問題ない。
引数 cq_context
は CQ におまけ的につけることのできる付加情報で、ibv_cq
構造体の cq_context
というメンバ変数にぶら下げることができる。
cq_context
メンバ変数に直接アクセスする以外では、completion event channel を使った場合に ibv_get_cq_event
で完了イベントの到着した CQ が渡されるが、引数 cq_context
でも渡される。
引数 channel
は説明が難しいが completion event channel を指定する。
5日の日記に書いたが CQ だけでは、CQ にエントリが積まれた瞬間が分からない。
Completion event channel を使うと epoll
などで CQ にイベントが入ったタイミングを検出できるようになる。
最後の引数 comp_vector
が難題である。
マニュアルには以下のようにある。
The CQ will use the completion vector comp_vector for signaling completion events; it must be at least zero and less than context->num_comp_vectors.
これは context->num_comp_vectors
未満の値を設定する必要があるらしい。
世の中のサンプルプログラムはたいがい comp_vector
に 0 が設定されている。
Completion vector の正体
Completion vector の正体は割り込みベクタ(IRQ)のようだ。
Completion event channel を使う場合、InfiniBand の HCA はハード割り込みをあげて CQ イベントの到着を通知しようとする。
この割り込み用の IRQ が複数個用意されており、その何番目を使うのを指示できる。
最大値は context->num_comp_vectors
で、規格上最小1個は用意されている。
Mellanox の InfiniBand HCA 用のドライバ mlx4 では、MSI-X の IRQ を(論理 CPU と同じ数)×(ポート数)分確保するようだ。
IRQ を複数持つのはイーサネットのマルチキュー NIC など使われる Receive Side Scaling(RSS) を実現するためだと思われる。
マルチコアシステムで論理 CPU が複数あって completion channel に CQ イベントの戸着を待っていても、IRQ が 1 つだと計算機の 1 論理 CPU にしか割り込みがあがらない。 これは「割り込みが 1 CPUで集中的に起きる」という CPU の負荷集中と、「割り込みが起きた CPU から別の CPU へイベントを(なんらかの手段で) completion channel を待っている CPU へ伝える」という遅延の点で問題となる。
mlx4 のように論理 CPU 数の IRQ を用意すると、個々の IRQ の SMP affinity を調整して各論理 CPU にバインドするように設定できる。
その上で ibv_create_cq
に comp_vector
を設定すると、completion channel 待ちをする CPU と CQ に割り込みがあがる CPU を一致させることができる。
参考
- [ofa-general][PATCH v2 1/2]mlx4: Multiple completion vectors support
- InfiniBand Trade Association | 仕様書のダウンロードページ
追記:2013/4/27
Mellanox HCA の場合、Linux カーネルバージョンによって HCA が作る IRQ の名前と数が異なる。
- RHEL5 のカーネルでは eth-mlx4-N という名前で、N には 0 から始まる CPU 番号が入る。論理 CPU が 16 個あれば、eth-mlx4-0 〜 eth-mlx4-15 の 16 個の IRQ ができる。
- RHEL6 のカーネルでは、少なくとも 6.3 までは、以下の 4 つしか作らない。
- mlx4-comp-N@pci:xxxx:xx:xx.x (N には 0〜2 が入る)
- mlx4-comp-async@pci:xxxx:xx:xx.x
- 最新のカーネルでは、上記に加えて以下を作る。
- mlx4-ib-C-N@PCI Bus xxxx:xx (C には 1 から始まる CPU ソケット番号が、N には 0 から始まる CPU ソケット内の論理 CPU 番号が入る)
- mlx4-ib-1-0@PCI Bus xxxx:xx 〜 mlx4-ib-1-7@PCI Bus xxxx:xx
- mlx4-ib-2-0@PCI Bus xxxx:xx 〜 mlx4-ib-2-7@PCI Bus xxxx:xx
9/22 (土)
ナマステ・インディア 2012
今年も代々木公園でナマステ・インディアが開催。 去年は2011年9月24日の日記。
象の広場 |
インドからの渡来僧で東大寺盧舎那仏像の開眼供養菩提僊那 |
|||
ジャンボタンドリーチキン串とパニプーリ |
タカタック マトンのミンチ肉のカレー炒めのようだ |
ココナッツマリブラッシーというのをソフトドリンクだろうと思って飲んだら、ココナッツラムのラッシー割だった。
江戸の判じ絵展@たばこと塩の博物館
代々木公園から公園通り坂を下ってゆくとあるたばこと塩の博物館で江戸の判じ絵展が開催されていたので見てゆく。 ここは百円で入れるので非常にコストパフォーマンスが良い。 前回は高野潤写真展「インカとアンデス原産植物」の特別展をやっていた。
渋谷で見つけた変な建物
1階の Disney に気をとられてよく見ていなかったけど、建物全体がかなり変。
9/16 (日)
[Movie] 天地明察
川崎チネチッタで観てる。 客の入りは半分ぐらい。
映画は小説から大胆な改変が加えられている。 小説版は安井算哲(渋川春海と名乗っているが)は北極出地から改暦までに20年近くかけその間山あり谷ありなのだが、映画版ではせいせい5年程度の時間に圧縮されている。 劇的な展開にするために山崎闇斎が殺されたり、ラストに蝕が起きたりする。 短い上映時間に盛り上げるためだろうから、個人的には OK だ。
[Food] タイ料理ティーヌン@川崎ダイス
相変わらず川崎ダイスにあるタイ料理のティーヌン(公式、ぐるなび、食べログ)に。 お店が少し改装されていた。 前回は6月30日に来ている。
プラー・ラー・プリック(揚げ魚の辛味ソースかけ)とゲーン・マッサマン(鶏肉とじゃがいものマッサマンカレー)を食べる。
9/15 (土)
ベトナムフェスティバル
今年も代々木公園でベトナムフェスティバルが開催された。 昨年は2011年9月18日に行っている。
カレーフォーと鳥串を食べる。
フレッシュ ココナッツ アイスクリームがあったが これはタイフェスティバルで食べたものと同じかしらん。 前回のは実際にココナッツの殻に入っていたが。
バナナのフライ。
代々木公園への遊歩道で犬がキックボードに乗っていた。
[Food] Napoli's PIZZA & CAFFE@渋谷
晩飯として渋谷のナポリスでピザを食べる。 前回は4月14日に行っている。
マルゲリータピッツァが 350 円が売りなのだが、個人的には味はちょっと思っている。 でも客は割と入っていた。
[Movie] バイオハザードV リトリビューション
渋谷の TOHO シネマズで『バイオハザードV リトリビューション』の3D字幕版を観る。
映画館が渋谷という立地のためか若いカップルがいっぱいで、おっさんには辛い。
9/14 (金)
[Linux] Core dump
Linux の場合、プロセス異常時のコアダンプには memory mapped file が入らなかったり hugetlb が入らなかったりする。
古いカーネルではこの判定は固定だが、カーネル 2.6.23 以降では /proc/PID/coredump_filter
が新設された。
coredump_filter
を読むとどのセグメントがコアダンプに含まれるか知ることができる。
coredump_filter
に書き込むことでコアダンプする対象になるセグメントの属性を変更することができる。
数値 | 意味 | 対象 |
---|---|---|
0x01 | ANON_PRIVATE | ヒープやスタック |
0x02 | ANON_SHARED | ファイルに関連付けられない共有メモリ。IPC 共有メモリ(shmget)や MAP_ANONYMOUS で mmap した後に fork した場合など。 |
0x04 | MAPPED_PRIVATE | これを付けるとほぼ全てのメモリがコアダンプ対象になる |
0x08 | MAPPED_SHARED | ファイルに関連付けられた共有メモリ |
0x10 | ELF_HEADERS | ELFヘッダーページ(これは基本的に含める) |
0x20 | HUGETLB_PRIVATE | Hugetlb のうち共有されていない部分 |
0x40 | HUGETLB_SHARED | Hugetlb のうち共有されている部分 |
9/13 (木)
[MyWeb] BIND の脆弱性
BIND 9 に Critical な脆弱性 が発見された。 9 系の全てのバージョンが外部からサービス停止させることができるとのこと。
nminoru.jp を担っている BIND を修正版の 9.9.1-P3 にアップデート。
9/9 (日)
ゴミ屋敷
南武線を向河原駅から川崎方向に進むと右手側にゴミ屋敷が見えてきていつも気になっていた。 今日は武蔵小杉から歩いてゴミ屋敷を直接見に行く。
電車から見るほどにはゴミが散らかっていないようだ。 人が住んでいるようにも見える。
有楽町で見た変なオブジェクト
有楽町の裏通りに等身大のブロンズ像がベンチに座っている。
豊洲オクトーバーフェスト
豊洲でオクトーバフェスト。
[Movie] デンジャラス・ラン
川崎チネチッタで「デンジャラスラン」観る。 原題は Safe House なので、これも背負ったタイトルだ。 ひげを剃る前後で別人のようになるデンゼル・ワシントンの演技がよろし。
9/6 (木)
[Food] マヤレストラン@武蔵小杉
「武蔵小杉ウォーカー」が発売されたので早速購入。 近場にはイタリア料理屋とインド料理屋が多いことを発見。
その中からインド料理「マヤレストラン」(公式、食べログ)へ行ってみる。 ジャガイモとカリフラワーのカレー「アルゴビ」を食べてみるが、この店のアルゴビは唐辛子がかなり利いていて他店のアルゴビとは趣が違う。 一番、好きなのはラージ・マハール(公式、食べログ)のアルゴビなんだけど、ここのも結構美味しい。
9/5 (水)
[Prog] InfiniBand Verbs の覚え書き
InfiniBand Verbs のライブラリ libibverbs の API の覚え書き。 マニュアルを読んでも分からない部分が多すぎる。
ibv_create_qp
ibv_create_qp は Queue Pair(QP) を作成する関数だが、QP の初期パラメータを指定する。
この中で sq_sig_all
と max_inline_data
の使い方が分からない。
マニュアルを読むと sq_sig_all
は If set, each Work Request (WR) submitted to the SQ generates a completion entry
、max_inline_data
は Requested max number of data (bytes) that can be posted inline to the SQ, otherwise 0
と説明されている。
これはこういう意味らしい。
- ibv_qp_init_attr の中にある sq_sig_all の意味
-
sq_sig_all
メンバ変数を非ゼロ値にセットすると、送信要求毎に完了イベント(completion event)を作ろうとする。 つまり Send Queue(SQ) へ挿れた Work Request(WR) が一つ処理されるごとに、Completion Queue(CQ) に CQE が積まれることになる。sq_sig_all
メンバ変数が 0 の場合には、成功した送信要求に対しては完了イベントを作らない(例外としてエラーが発生した送信要求に対する完了イベントは挿入される)。 そのためibv_poll_cq
で処理する CQE の数が減る。 ただし送信要求したことが検知できなくなる。sq_sig_all
メンバ変数が 0 の場合でも、個別の送信要求ごとに完了イベントを発生させることができる。 これはibv_pos_send
を呼ぶ時に WR のsend_flags
メンバ変数に対して IBV_SEND_SIGNALED を設定する。なお
sq_sig_all
メンバ変数が 0 の場合でも、受信要求に対する完了イベントは発生し CQ に積まれる。 - ibv_qp_cap の中にある max_inline_data の意味
-
ibv_post_send
で SEND (with Immediate Data も含む)を実行する場合、ibv_sge 指定したローカルメモリバッファは SEND の実行が完了するまで維持する必要がある(つまり Completion Queue(CQ) に work completion が届くまで)。 途中でバッファの内容を書き換えると送信内容の一貫性は保証されない。 しかしibv_post_send
のsend_flags
に IBV_SEND_INLINE を付けた場合、バッファの内容がカーネル内のメモリ領域にバックアップされるのでバッファを直ちに破棄できるようになる。max_inline_data
メンバ変数はこの目的のために使うバッファコピー領域の最大を指定する。 指定のメモリがカーネルランドに予約されることになる。Mellanox ではこの機能は使えないかもしれない。
ibv_post_send
ibv_post_send の send_flags
の設定パラメータが意味が分からない。
The attribute send_flags describes the properties of the WR. It is either 0 or the bitwise OR of one or more of the following flags:
IBV_SEND_FENCE Set the fence indicator. Valid only for QPs with Transport Service Type IBV_QPT_RC
IBV_SEND_SIGNALED Set the completion notification indicator. Relevant only if QP was created with sq_sig_all=0
IBV_SEND_SOLICITED Set the solicited event indicator. Valid only for Send and RDMA Write with immediate
IBV_SEND_INLINE Send data in given gather list as inline data in a send WQE. Valid only for Send and RDMA Write. The L_Key will not be checked.
以上のパラメータを IB Verbs のソース、Linux カーネルのソース、InfiniBand Architecture Specification を読んだ上で以下のように理解した。
- IBV_SEND_FENCE
-
InfiniBand 的には fence indicator をセットすることを意味する。 これは IBV_QPT_RC の時のみ有効。
InfiniBand の操作のうち SEND(with Immediate Data も含む)と RDMA WRITE(with Immediate Data も含む)は実行順序が保証されるが、RDMA READ(with Immediate Data も含む)とアトミック処理(Comapre and Swap、Fetch and Add)は保証されず実行順序が逆転する可能性がある。 IBV_SEND_FENCE を付けるとは全ての操作の実行順序が保証される。
実際は、HCA がこのフラグの立っている WR を処理する時に、先行する全ての送信要求の終了を待つ。
詳細は InfiniBand Architecture Specification Volume 1 Release 1.2.1 の 10.8.3 WORK REQUEST PROCESSING を見ること。
- IBV_SEND_SIGNALED
-
上の
ibv_create_qp
のsq_sig_all
メンバ変数の説明のように、sq_sig_all
が 0 の QP は通常の送信要求で完了イベントが送られない。 ただし IBV_SEND_SIGNALED を付けた WR 分は、実行後に CQ に完了イベント(work completion)が積まれることになる。sq_sig_all
が 0 で IBV_SEND_SIGNALED を付けない場合でも、エラーとなった送信要求は完了イベントが通知される。 また受信要求に対する完了イベントは CQ に積まれる。詳細は InfiniBand Architecture Specification Volume 1 Release 1.2.1 の 10.7.3.1 SIGNALED COMPLETIONS を見ること。
- IBV_SEND_SOLICITED
-
InfiniBand の仕様では送信処理(Send Work)と受信処理(Receive Work)が終わった場合、Completion Queue(CQ) に処理完了(Work Compeltion)のイベントが挿入される。 もし completion channel を使っていると、CQ に WC が積まれるタイミングで completion channel が ready-to-input の状態になる。 Completion channel を使って待ち合わせをしていたスレッドは待機状態が解けることになる。
しかし comletion channel を使った待機が任意の WC で解けるのは効率がよくない。 そこで
ibv_post_sned
で送信処理要求(Send Work Request)を投げる際に、IBV_SEND_SOLICITED を付けたのを Solicited(応答型) とする。 この操作によるメッセージが送信先に届いた場合、送信先では Solicited Competion Event が発生する。また Send WR、Receive WR を問わず完了エラー(IBV_WC_SUCCESS 以外の WC)は緊急性が高いので、Solicited Completion Event となる。
これ以外の completion event、つまり成功した Send WR と、IBV_SEND_SOLICITED を付けずに送られた操作の成功した Receive WR は Unsolicited Completion Event となる。
送信先に work completion を作り出すのは SEND、SEND with Immediate Data、RDMA Write with Immediate Data の 3 つの操作のみである。 これ以外の RDMA Wwrite without Immediate Data、RDMA Read、Atomic 操作は送信先に work completion を作り出さない。 IBV_SEND_SOLICITED は SEND、SEND with Immediate Data、RDMA Write with Immediate Data の 3 つのみにつけることができ、それ以外の操作につけるとどうなるかはマニュアルに記述がないが InfiniBand の仕様的には N/A である。
InfiniBand は compeltion event の到着を epoll や select 型のようなブロッキングスタイルで待つ場合と、compeltion event が到着してもトリガーを起こさず自分で定期的にポーリングするやり方がある。 前者の場合には completion event channel を作る。 これは
ibv_create_comp_channel
で作った channel を CQ にリンクし、compeltion event が到着するまでibv_get_cq_event
で待機するやり方だ。 模式的なコードで説明すると以下のようになる。context = ibv_open_device(ib_dev); channel = ibv_create_comp_channel(context); cq = ibv_create_cq(context, rx_depth, NULL, channel, 0); // Compeltion の到着を ibv_get_cq_event で検出できるように設定 ibv_req_notify_cq(cq, solicited_only); #if 0 flags = fcntl(channel->fd, F_GETFL); fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK); #endif // 途中省略 struct ibv_cq *ev_cq; void *ev_ctx; // Compeltion が来るまで待機 #if 0 my_pollfd.fd = channel->fd; my_pollfd.events = POLLIN; my_pollfd.revents = 0; poll(&my_pollfd, 1, timeout); #endif ibv_get_cq_event(channel, &ev_cq, &ev_ctx); // 次回の compeltion の到着を ibv_get_cq_event で検出できるように設定 ibv_req_notify_cq(cq, solicited_only); struct ibv_wc wc[max]; while ((ret = ibv_poll_cq(cq, max, wc)) > 0) { // 処理 } ibv_ack_cq_events(cq, 1);
Channel の監視は
ibv_req_notify_cq
を呼び出した時から始まる。ibv_get_cq_event
は one-shot 動作なのでibv_req_notify_cq
は監視の度に呼び出す必要がある。ibv_req_notify_cq
の呼び出しの際に solicited_only フラグがあり、これが非 0 の場合は channel は「solicited な処理完了だけ」を検知するようになる。 そのため solicited_only に 1 を指定する場合はibv_post_send
で処理を投げる時にsend_flags
フラグに IBV_SEND_SOLICITED を付けないと駄目だ(ibv_get_cq_event
が永遠に止まってしまう)。ibv_get_cq_event
は、タイムアウト時間の指定を引数に取れないし、待機中にシグナルを受信したら EINTR で戻る等の規定がない。 だから普通は上記コードの灰色のコード用に channel 内の file descriptor を使って epoll や select で待機するのがよろし。一方、solicited_only フラグが 0 の場合には「solicited と unsolicited の両方の処理完了」を検知する。 一般的には 0 を指定する。
- IBV_SEND_INLINE
-
上の
ibv_create_qp
のmax_inline_data
メンバ変数の説明のように、IBV_SEND_INLINE を付けた場合には WR がポイントするバッファの内容がカーネル内の別バッファにコピーされる。 そのため IBV_SEND_INLINE を付けた場合、ibv_post_send
から復帰した時点でバッファを破棄できる。 また IBV_SEND_INLINE を付けない場合 ibv_sge の lkey でローカルバッファの L_key のチェックが行われるが、IBV_SEND_INLINE を付ける場合にはこのチェックは行われない。ただしバッファのコピーが増えるので遅くなる。
参考
- The Geek in the Corner | RDMA read and write with IB verbs コメントを含めて
- InfiniBand Trade Association | 仕様書のダウンロードページ
追記:2014/1/27
IBV_SEND_SOLICITED の説明に間違いがあったので書き直した。
9/1 (土)
[MyWeb] 「ビットを数える・探すアルゴリズム」のページを修正
久しぶりにビットを数える・探すアルゴリズムのページを修正した。
Core i5-2400 3.1GHz での性能測定データとかを載せてみる。