Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

kenjihanada
February 22, 2019

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

by kawashin73

kenjihanada

February 22, 2019
Tweet

More Decks by kenjihanada

Other Decks in Technology

Transcript

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

    View full-size slide

  2. 言語の壁をぶっ壊す

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  5. エンディアンとは

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  11. 言語の壁をぶっ壊す

    View full-size slide

  12. unsafe.Pointer だ!!

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  19. なんでや

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide