Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

N. Shimizu / @chikoski •Mozilla Japan で Developer relation (エヴァンジェリスト)をしています
 JavaScript, asm.js, WASM, DevTools, Rust, etc •ドキュメントの翻訳や、製品の翻訳も行なっています •コミュニティ活動: •html5j Web プラットフォーム部 / ゲーム部 •We are JavaScripters •プログラミング言語そのものが好きです •https://speakderdeck.com/chikoski/

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

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/)

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

GVODUJPOVQEBUF \ CFGPSF6QEBUF  VQEBUF0CKFDU4UBUVT  VQEBUF(SBQIJDT  BGUFS6QBUF  XJOEPXSFRVFTU"OJNBUJPO'SBNF VQEBUF  ^  window.requestAnimationFrame を利用したアニメーションの描画ループ

Slide 10

Slide 10 text

WPJENBJO \ XIJMF USVF \ֿך搀ꣲٕ٦فכ04ח״׏גծ黝㹅♧儗⨡姺ׁ׸תׅ CFGPSF@VQEBUF  VQEBUF@PCKFDU@TUBUVT  VQEBUF@HSBQIJDT  BGUFS@VQEBUF  ^ ^ 典型的なアニメーションループ

Slide 11

Slide 11 text

GVODUJPOEP5BTL \ EP5BTL"  EP5BTL#  EP5BTL$  EP5BTL%  ^ אה׮װ׷חכ儗꟦ַַָ׶ֺׅ׷ GVODUJPOEP5BTL \ EP5BTL"  EP5BTL#  XJOEPXTFU*NNFEJBUF \ EP5BTL$  EP5BTL%  ^  ^ window.setImmediateを利用した、明示的な処理時間の移譲

Slide 12

Slide 12 text

GVODUJPOMPX1SJPSJUZ5BTL EFBEMJOF \ JG EFBEMJOFUJNF3FNBJOJOH  \ EP4PNFUIJOH  ^ ^ XJOEPXSFRVFTU*EMF$BMMCBDL MPX1SJPSJUZ5BTL  XJOEPXSFRVFTU*EMF$BMMCBDL MPX1SJPSJUZ5BTL \UJNFPVU^  空き時間にする処理の登録

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

DPOTUXPSLFSOFX8PSLFS XPSLFSKT 8PSLFSך⡲䧭 8PSLFSַ׵ךًحإ٦آ׾「ֽ《׷عٝسٓ XPSLFSPONFTTBHFNFTTBHF\ DPOTUEBUBNFTTBHFEBUB EPTPNFUIJOH ^ ً؎ٝفؚٗٓيַ׵8PSLFSפךًحإ٦آך鷏⥋
 XPSLFSTFOE.FTTBHF \DPNNBOETVN OVNCFST<   >^  Workerを利用するプログラムの例:mainスレッド側

Slide 17

Slide 17 text

JNQPSU4DSJQUT DPNNBOEKT أؙٔفزך؎ٝه٦ز PONFTTBHFFWFOU\ DPOTUEBUBNFTTBHFEBUB DPOTU\OBNF OVNCFST^EBUB DPOTUDPNNBOEHFU$PNNBOE#Z/BNF OBNF  DPOTUSFTVMUDPNNBOE OVNCFST  QPTU.FTTBHF \DPNNBOEOBNF SFTVMUSFTVMU^  ^ Workerを利用するプログラムの例:ワーカースレッド側

Slide 18

Slide 18 text

DPOTUPCK\WBMVF^ XPSLFSQPTU.FTTBHF PCK  XPSLFSPONFTTBHF EBUB\ DPOTPMFMPH PCKEBUB  ^  PONFTTBHFGVODUJPO EBUB \ QPTU.FTTBHF EBUB  ^ main worker メッセージを通じて渡されるオブジェクトはコピーされる

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

DPOTUCVGGFSOFX"SSBZ#VGGFS  غ؎زך㔿㹀ꞿךꂁ⴨׾然⥂ DPOTUWJFXOFX*OU"SSBZ CVGGFS  غ؎زךꂁ⴨׾ؽحزך侭侧ךꂁ⴨ה׃ג،ؙإأׅ׷׋׭ךؽُ٦׾⡲䧭 GPS MFUJJWJFXMFOHUIJ \ WJFX.BUIGMPPS .BUISBOEPN  /VNCFS."9@4"'&@*/5&(&3  ^ 格納するデータの種類に合わせたビューを作成し、そのビューを通じてアクセスする

Slide 21

Slide 21 text

ؽُ٦ ؟؎ؤ 铡僇 ず瘝ך$ך㘗 *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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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で受け渡した後も領域を参照できます

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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;

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

食事する哲学者の問題 • 複数プロセスの同期制御に関する古典的な問題 • 問題: • 哲学者が円卓を囲んでいる • 哲学者はときおり考えるのやめて、食事をする • 食事には2本のフォークが必要で、
 一度には1本のフォークしかとれない • 哲学者同士は会話をしない • 哲学者は食事することがきるだろうか? IUUQTKBXJLJQFEJBPSHXJLJ굸✲ׅ׷ㆸ㷕罏ך㉏겗

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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 起こすメインスレッドと、待つワーカースレッド

Slide 36

Slide 36 text

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 生産者と消費者

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

IUUQTCMPHTVOJUZEDPNKQVQEBUFEXFCHMCFODINBSLSFTVMUT

Slide 39

Slide 39 text

.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