Slide 1

Slide 1 text

俺はビッグエンディアンでテス トがしたいんだ! @kawasin73

Slide 2

Slide 2 text

言語の壁をぶっ壊す

Slide 3

Slide 3 text

自己紹介 かわしん @kawasin73 東京大学工学部システム創成学科 3年生 (2年半休学してました) DMM.com のCTO室で、Go言語でデータベースを作るインターン この1年半くらいGo。それまでは、Rails、iOS、Android、Webフロントなど 趣味は特にない(強いて挙げれば蟻の飼育)

Slide 4

Slide 4 text

ビットベクトルライブラリを作ってテストした Go 言語で マシンエンディアンに関わらず 指定されたエンディアンで動く ビットベクトルライブラリを作ってテストを行った https://github.com/kawasin73/bitset ビットベクトル:[]bool の省メモリ版データ構造

Slide 5

Slide 5 text

エンディアンとは

Slide 6

Slide 6 text

エンディアンはバイトの並び順(バイトオーダーとも) 例えば uint64 は 8 バイトの数値。その中身がどのように配置されているか ビッグエンディアン 0x0123456789abcdef → 0x01 | 0x23 | 0x45 | 0x67 | 0x89 | 0xab | 0xcd | 0xef リトルエンディアン → 0xef | 0xcd | 0xab | 0x89 | 0x67 | 0x45 | 0x23 | 0x01 エンディアンとは

Slide 7

Slide 7 text

エンディアンはどう決まるのか エンディアンは CPU によって違う。 amd64 (Intel) など → リトルエンディアン arm など → ビッグエンディアン CPU によっては切り替えることもできる

Slide 8

Slide 8 text

エンディアンはいつ気にするのか? バイナリで外部とのやりとり(ファイル読み書き、ネットワーク通信)する時 エンディアンが違うと正しい値を読み取れない。 ビッグエンディアンの uint64(1) → リトルエンディアンのuint64(72057594037927936) 普通は、ネットワークライブラリがエンディアン処理をしているので、気にする必要はな い。

Slide 9

Slide 9 text

Go でのエンディアン "encoding/binary" パッケージが用意されている binary.BigEndian.PutUint64(bytes, v) binary.LittleEndian.Uint64(bytes) Go ではエンディアンは露出しない。uint64 のビットの順番は環境に寄らず同じ

Slide 10

Slide 10 text

課題 ファイルへの読み書きを頻繁に行う時 毎回エンディアン処理を行うのはオーバーヘッドになる。

Slide 11

Slide 11 text

言語の壁をぶっ壊す

Slide 12

Slide 12 text

unsafe.Pointer だ!!

Slide 13

Slide 13 text

unsafe.Pointer マシンエンディアンで直接扱うために、unsafe.Pointer を使って []byte から []uint64 に 強制キャストをしている。

Slide 14

Slide 14 text

壊したので unsafe.Pointer によって壊したので、どのエンディアンの環境でも正しく動くかをテストす る必要がある。

Slide 15

Slide 15 text

俺はビッグエンディアンでテス トがしたいんだ! @kawasin73 本編

Slide 16

Slide 16 text

Travis CI で自動テスト Travis CI の CPU アーキテクチャは amd64 (リトルエンディアン)のみ Travis CI でビッグエンディアンでテストする手法を探す → QEMU でビッグエンディアンの CPU をエミュレートする

Slide 17

Slide 17 text

qemu で go test Linux で Go の実行環境をインストールできるのは以下のCPUアーキテクチャ amd64, 386, arm, arm64, s390x, ppc64le この中で、ビッグエンディアンなのは s390x https://golang.org/doc/install#requirements ※ arm はリトルエンディアン、armbe がビッグエンディアン

Slide 18

Slide 18 text

qemu-ppc64-static で go test 無慈悲なエラー

Slide 19

Slide 19 text

なんでや

Slide 20

Slide 20 text

go test はできない 原因は不明。Go が悪いのか qemu が悪いのか。 qemu が特定の CPU 命令に対応していない? 行き詰まった。

Slide 21

Slide 21 text

救世主

Slide 22

Slide 22 text

おい、テストを コンパイルできるらしいぞ

Slide 23

Slide 23 text

コンパイルできると可能性が広がる ビッグエンディアンに対応している ppc64, mips, mips64, s390x ppc64 だとうまくいった

Slide 24

Slide 24 text

結論

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

よっしゃ https://travis-ci.com/kawasin73/bitset/jobs/172066523

Slide 27

Slide 27 text

参考資料 ブログ記事 https://kawasin73.hatenablog.com/entry/2018/12/01/172708 対応した github issue https://github.com/kawasin73/bitset/issues/5