$30 off During Our Annual Pro Sale. View Details »

20161113-nodefest

chikoski
November 13, 2016

 20161113-nodefest

chikoski

November 13, 2016
Tweet

More Decks by chikoski

Other Decks in Technology

Transcript

  1. JavaScriptでの並列プログラミング: 共有メモリーと不可分操作、ロック
    N.Shimizu ([email protected])
    東京node学園祭(2016/11/13)

    View Slide

  2. N. Shimizu / @chikoski
    •Mozilla Japan で Developer relation (エヴァンジェリスト)をしています

    JavaScript, asm.js, WASM, DevTools, Rust, etc
    •ドキュメントの翻訳や、製品の翻訳も行なっています
    •コミュニティ活動:
    •html5j Web プラットフォーム部 / ゲーム部
    •We are JavaScripters
    •プログラミング言語そのものが好きです
    •https://speakderdeck.com/chikoski/

    View Slide

  3. View Slide

  4. View Slide

  5. Proudly non-profit, Mozilla makes products like Firefox with a
    mission to keep the power of the Web in the hands of users
    everywhere.
    Mozilla Mission (https://www.mozilla.org/en-US/mission/)

    View Slide

  6. Our mission is to promote
    openness, innovation & opportunity on the Web.
    Mozilla Mission(https://www.mozilla.org/en-US/mission/)

    View Slide

  7. Project Positron(Geckoを使用したElectron互換のアプリシェル) : https://github.com/mozilla/positron

    View Slide

  8. JavaScriptはメインスレッドの時間を譲り合って共有します
    • 非同期処理を行うことで、実行時間を他のプログラムに譲れます
    • 例:アニメーション
    • スケジューラーがある場合:アニメーションを行う長い繰り返し処理
    • JS: 1フレームごとの処理に分割し、window.requestAnimationFrameで他のプログラムに時間を譲る
    1フレームの処理 1フレームの処理 1フレームの処理
    非同期

    処理
    非同期

    処理
    非同期

    処理
    他の処理 他の処理

    View Slide

  9. GVODUJPOVQEBUF
    \
    CFGPSF6QEBUF

    VQEBUF0CKFDU4UBUVT

    VQEBUF(SBQIJDT

    BGUFS6QBUF

    XJOEPXSFRVFTU"OJNBUJPO'SBNF VQEBUF

    ^
     window.requestAnimationFrame を利用したアニメーションの描画ループ

    View Slide

  10. WPJENBJO
    \
    XIJMF USVF
    \ֿך搀ꣲٕ٦فכ04ח״׏גծ黝㹅♧儗⨡姺ׁ׸תׅ
    CFGPSF@VQEBUF

    VQEBUF@PCKFDU@TUBUVT

    VQEBUF@HSBQIJDT

    BGUFS@VQEBUF

    ^
    ^
    典型的なアニメーションループ

    View Slide

  11. GVODUJPOEP5BTL
    \
    EP5BTL"

    EP5BTL#

    EP5BTL$

    EP5BTL%

    ^
    אה׮װ׷חכ儗꟦ַַָ׶ֺׅ׷
    GVODUJPOEP5BTL
    \
    EP5BTL"

    EP5BTL#

    XJOEPXTFU*NNFEJBUF
    \
    EP5BTL$

    EP5BTL%

    ^

    ^
    window.setImmediateを利用した、明示的な処理時間の移譲

    View Slide

  12. GVODUJPOMPX1SJPSJUZ5BTL EFBEMJOF
    \
    JG EFBEMJOFUJNF3FNBJOJOH

    \
    EP4PNFUIJOH

    ^
    ^
    XJOEPXSFRVFTU*EMF$BMMCBDL MPX1SJPSJUZ5BTL

    XJOEPXSFRVFTU*EMF$BMMCBDL MPX1SJPSJUZ5BTL \UJNFPVU^

    空き時間にする処理の登録

    View Slide

  13. メインスレッドだけを効率よく使うには
    • 仕事を適切な粒度に分解して、分解された仕事と仕事の間に適切に非同期処理を入れてやる
    • window.requestAnimationFrame
    • window.setTimeout, window.setInterval, window.setImmediate
    • 隙間時間に仕事をうまく入れていく: window.requestIdleCallBack
    • 1つのスレッドを効率よく使う、というアプローチには限界があります
    • 凝集度が下がり、プログラムは読みにくくなります
    • 仕事をどうしても分割できない場合もあります

    View Slide

  14. マルチスレッドプログラミング

    View Slide

  15. マルチスレッドプログラムとは
    • 複数の処理の流れ(スレッド)を利用するプログラムのこと
    • JavaScriptではWeb Workersを利用することで、マルチスレッドプログラムを実現できます
    taskA taskB
    TaskC
    taskD
    taskA taskB taskA
    taskD taskD taskD taskD taskD taskD

    View Slide

  16. DPOTUXPSLFSOFX8PSLFS XPSLFSKT
    8PSLFSך⡲䧭
    8PSLFSַ׵ךًحإ٦آ׾「ֽ《׷عٝسٓ
    XPSLFSPONFTTBHFNFTTBHF\
    DPOTUEBUBNFTTBHFEBUB
    EPTPNFUIJOH
    ^
    ً؎ٝفؚٗٓيַ׵8PSLFSפךًحإ٦آך鷏⥋

    XPSLFSTFOE.FTTBHF \DPNNBOETVN OVNCFST< >^

    Workerを利用するプログラムの例:mainスレッド側

    View Slide

  17. JNQPSU4DSJQUT DPNNBOEKT
    أؙٔفزך؎ٝه٦ز
    PONFTTBHFFWFOU\
    DPOTUEBUBNFTTBHFEBUB
    DPOTU\OBNF OVNCFST^EBUB
    DPOTUDPNNBOEHFU$PNNBOE#Z/BNF OBNF

    DPOTUSFTVMUDPNNBOE OVNCFST

    QPTU.FTTBHF \DPNNBOEOBNF SFTVMUSFTVMU^

    ^
    Workerを利用するプログラムの例:ワーカースレッド側

    View Slide

  18. DPOTUPCK\WBMVF^
    XPSLFSQPTU.FTTBHF PCK

    XPSLFSPONFTTBHF EBUB\
    DPOTPMFMPH PCKEBUB

    ^

    PONFTTBHFGVODUJPO EBUB
    \
    QPTU.FTTBHF EBUB

    ^
    main worker
    メッセージを通じて渡されるオブジェクトはコピーされる

    View Slide

  19. ArrayBuffer:固定長のバイト列
    • 固定長のバイナリーデータを扱うためのデータ構造です
    • 各要素へ直接アクセスすることはできません
    IUUQDBOJVTFDPNTFBSDI"SSBZ#VGGFS

    View Slide

  20. DPOTUCVGGFSOFX"SSBZ#VGGFS
    غ؎زך㔿㹀ꞿךꂁ⴨׾然⥂
    DPOTUWJFXOFX*OU"SSBZ CVGGFS

    غ؎زךꂁ⴨׾ؽحزך侭侧ךꂁ⴨ה׃ג،ؙإأׅ׷׋׭ךؽُ٦׾⡲䧭
    GPS MFUJJWJFXMFOHUIJ
    \
    WJFX.BUIGMPPS .BUISBOEPN
    /VNCFS."9@4"'&@*/5&(&3

    ^
    格納するデータの種類に合わせたビューを作成し、そのビューを通じてアクセスする

    View Slide

  21. ؽُ٦ ؟؎ؤ 铡僇 ず瘝ך$ך㘗
    *OU"SSBZ 痗〾אֹ侭侧ך酡侧 JOU@U
    6JOU"SSBZ 痗〾ז׃侭侧 VJOU@U
    6JOU$MBNQU"SSBZ 痗〾ז׃侭侧ؙٓٝف VJOU@U
    *OU"SSBZ 痗〾אֹ侭侧ך酡侧 JOU@U
    6JOU"SSBZ 痗〾ז׃侭侧 VJOU@U
    *OU"SSBZ 痗〾אֹ侭侧ך酡侧 JOU@U
    6*OU"SSBZ 痗〾ז׃侭侧 VJOU@U
    'MPBU"SSBZ 嵤⹛㼭侧挿 PBU
    'MPBU"SSBZ ⦓礵䏝嵤⹛㼭侧挿 EPVCMF

    View Slide

  22. GFUDI BFODPEFE

    UIFO SSBSSBZ#VGGFS


    UIFO CVG\
    XPSLFSQPTU.FTTBHF CVG

    ^

    XPSLFSPO.FTTBHFEP4PNF5IJOH
    PONFTTBHFGVODUJPO EBUB
    \
    DPOTUWJFX
    OFX*OU"SSBZ EBUB

    EFDPEF WJFX

    QPTU.FTTBHF WJFXCVGGFS

    ^
    データがなんどもコピーされて非効率
    main worker

    View Slide

  23. DPOTUCVGGFSOFX"SSBZ#VGGFS

    GVODUJPOUSBOTGFS
    \
    DPOTPMFMPH CVGGFS
    խ"SSBZ#VGGFS\CZUF-FOHUI^
    XPSLFSQPTU.FTTBHF CVGGFS

    DPOTPMFMPH CVGGFS
    "SSBZ#VGGFS\CZUF-FOHUI^
    DPOTPMFMPH CVGGFSCVGGFS
    USVF
    ^
    ArrayBufferは、その所有権をスレッド間で移動できます

    View Slide

  24. GFUDI BFODPEFE

    UIFO SSBSSBZ#VGGFS


    UIFO CVG\
    XPSLFSQPTU.FTTBHF CVG

    ^

    XPSLFSPO.FTTBHFEP4PNF5IJOH

    PONFTTBHFGVODUJPO EBUB
    \
    DPOTUWJFX
    OFX*OU"SSBZ EBUB

    EFDPEF WJFX

    QPTU.FTTBHF WJFXCVGGFS


    ^
    所有権の移動を利用したコード
    main worker

    View Slide

  25. メインスレッドをブロックしなくても、重たい処理を行えるように
    • Web Workers を利用することで、メインスレッド以外にスレッドを作成できます
    • 作成したスレッドで重たい処理をすれば、メインスレッドを占有することはありません
    • 大きなArrayBufferは所有権を移動させることで、効率よく転送できます
    fetch task
    decode
    doSomething
    task task task task task
    QPTU.FTTBHF QPTU.FTTBHF

    View Slide

  26. 3つ以上のスレッドで、ArrayBufferを共有するには?
    • データを利用した処理を複数の主体で行う場合もあります
    • 同じデーターに対して、異なる処理をする場合
    • 同じデーターの異なる部分に対して、同じ処理をする場合
    • 所有権は1つのスレッドしか持てないので、データをコピーするしかない?
    أٖحس
    "SSBZ#VGGFS
    أٖحس
    "SSBZ#VGGFS
    ずׄ"SSBZ#VGGFS׾䭯ג׷ךַ

    View Slide

  27. SharedArrayBuffer
    • スレッド間で共有可能なArrayBuffer
    • ArrayBuffer同様、ビュー経由で要素にアクセスします
    • "ECMAScript Shared Memory and Atomics" で提案中です

    http://tc39.github.io/ecmascript_sharedmem/shmem.html
    أٖحس
    4IBSFE"SSBZ#VGGFS
    أٖحس
    4IBSFE"SSBZ#VGGFS
    4IBSFE"SSBZ#VGGFS

    View Slide

  28. DPOTUCVGGFSOFX4IBSFE"SSBZ#VGGFS

    GVODUJPOUSBOTGFS
    \
    DPOTPMFMPH CVGGFS
    խ4IBSFE"SSBZ#VGGFS\CZUF-FOHUI^
    XPSLFSQPTU.FTTBHF CVGGFS

    DPOTPMFMPH CVGGFS
    4IBSFE"SSBZ#VGGFS\CZUF-FOHUI^
    DPOTPMFMPH CVGGFSCVGGFS
    USVF
    ^
    共有されているので、postMessageで受け渡した後も領域を参照できます

    View Slide

  29. DPOTUIFBQ
    OFX6*OU"SSBZ CVGGFS

    IFBQ<>IFBQ<>
    DPOTUIFBQ
    OFX6*OU"SSBZ CVGGFS

    IFBQ<>
    2つの計算が終わった時、view[0] にはなにが入っているでしょうか?
    threadA threadB

    View Slide

  30. heap[0] = heap[0] == 0 ? 2 : 0; はいくつかの処理に分割されます
    a = [0]; a = a + 2; view[0] = a; view[0] = 1;
    a = view[0]; a = a + 2; view[0] = a;
    view[0] = 1;
    a = view[0]; a = a + 2; view[0] = a;
    view[0] = 1;

    View Slide

  31. 共有メモリには、Atomicsオブジェクトの提供する不可分操作を利用してアクセス します
    DPOTUIFBQOFX6*OU"SSBZ CVGGFS

    "UPNJDTDPNQBSF&YIBOHF IFBQ

    DPOTUIFBQOFX6*OU"SSBZ CVGGFS

    IFBQ<>IFBQ<>
    Atomics利用
    Atomicsなし

    View Slide

  32. ꟼ侧 铡僇
    "UPNJDTBEE 䭷㹀⡘縧ך⦼הך⸇皾׾遤ְծ׉ך穠卓׾׉ך⡘縧ח剅ֹ䨱ׅ
    "UPNJDTBOE 䭷㹀⡘縧ך⦼הך锷椚琎׾鎘皾ׅ׷
    "UPNJDTDPNQBSF&YDIBOHF 䭷㹀⡘縧ך⦼ה嫰鯰׾遤ְծ瘝׃ְ㜥さծ׉ך⡘縧ך⦼׾縧ֹ䳔ִ׷
    "UPNJDTFYDIBOHF 䭷㹀⡘縧ך⦼׾ծⴽך⦼הⰅ׸剏ִ׷
    "UPNJDTMPBE 䭷㹀⦼ך⦼׾《䖤ׅ׷
    "UPNJDTPS 䭷㹀⡘縧ך⦼הך锷椚ㄤ׾鎘皾ׅ׷
    "UPNJDTTUPSF 䭷㹀⡘縧ח⦼׾鏣㹀ׅ׷
    "UPNJDTTVC 䭷㹀⡘縧ך⦼הך幾皾׾遤ְծ׉ך穠卓׾׉ך⡘縧ח剅ֹ䨱ׅ
    "UPNJDTYPS 䭷㹀⡘縧ך⦼הך䱖➭涸锷椚ㄤ׾鎘皾ׅ׷

    View Slide

  33. 食事する哲学者の問題
    • 複数プロセスの同期制御に関する古典的な問題
    • 問題:
    • 哲学者が円卓を囲んでいる
    • 哲学者はときおり考えるのやめて、食事をする
    • 食事には2本のフォークが必要で、

    一度には1本のフォークしかとれない
    • 哲学者同士は会話をしない
    • 哲学者は食事することがきるだろうか?
    IUUQTKBXJLJQFEJBPSHXJLJ굸✲ׅ׷ㆸ㷕罏ך㉏겗

    View Slide

  34. Atomics.wait / Atomics.wake
    • 特定の条件が true になるまで待つ手段
    • 待っている間、処理はその式でブロックされる
    • 起動されると、その式以降から実行が継続されます
    • 条件の指定方法、
    • 共有された指定位置の値が、指定された値と等しい間、待ちます
    • 使用できるのは、共有されたInt32Arrayのみ
    • Atomics.waitをメインスレッドで呼ぶことはできません

    View Slide

  35. XPSLFSQPTU.FTTBHF IFBQCVGGFFS


    EP4PNFUIJOH
    "UPNJDTXBLF IFBQ

    "UPNJDTTUPSF IFBQ

    "UPNJDTXBLF IFBQ

    PONFTTBHFGVODUJPO CVGGFS
    \
    DPOTUIFBQ
    OFX6*OU"SSBZ CVGGFS

    DPOTPMFMPH "UPNJDTMPBE IFBQ


    "UPNJDTXBJU IFBQ

    DPOTPMFMPH "UPNJDTMPBE IFBQ


    main worker
    起こすメインスレッドと、待つワーカースレッド

    View Slide

  36. DPOTU7"-*%
    DPOTU*/7"-*%
    "UPNJDTTUPSF IFBQ */7"-*%

    XPSLFSQPTU.FTTBHF IFBQCVGGFS


    QSPEVDF IFBQ

    "UPNJDTTUPSF IFBQ 7"-%*%

    "UPNJDTXBLF IFBQ

    DPOTU*/7"-*%
    PONFTTBHFGVODUJPO CVGGFS
    \
    DPOTUIFBQ
    OFX6*OU"SSBZ CVGGFS

    "UPNJDTXBJU IFBQ */7"-*%

    DPOTVNF IFBQ

    ^
    main worker
    生産者と消費者

    View Slide

  37. DPOTU4*(/"&-&%
    DPOTU&7&/5@"
    GVODUJPOGJSF RVFVF FWFOU5ZQF
    \
    "UPNJDTTUPSF RVFVF
    FWFOU5ZQF
    4*(/"-&%

    "UPNJDTXBLF RVFVF FWFOU5ZQF

    ^
    GJSF RVFVF &7&/5@"

    DPOTU6/4*(/"-&%
    DPOTU&7&/5@"
    "UPNJDTXBJU RVFVF
    &7&/5@"
    6/4*(/"-&%

    IBOEM&WFOU"

    main worker
    Event object

    View Slide

  38. IUUQTCMPHTVOJUZEDPNKQVQEBUFEXFCHMCFODINBSLSFTVMUT

    View Slide

  39. .BJO5ISFBE 8PSLFS5ISFBE
    CVGGFS CVGGFS
    CVGGFS CVGGFS
    CVGGFS
    CVGGFS CVGGFS
    DPQZ
    5SBOTGFS
    3FGFS
    3FGFS
    DPOTUCVGGFSOFX"SSBZ#VGGFS

    XPSLFSQPTU.FTTBHF CVGGFS

    DPOTUCVGGFSOFX"SSBZ#VGGFS

    XPSLFSQPTU.FTTBHF CVGGFS

    DPOTUCVGGFSOFX4IBSFE"SSBZ#VGGFS

    XPSLFSQPTU.FTTBHF CVGGFS

    View Slide