SlideShare uma empresa Scribd logo
1 de 43
Baixar para ler offline
Project Loom
櫻庭 祐一
Project Panama
Alan Bateman Richard Bäckman
Project Loom
Background
How to Use
Performance
Thread
Fiber
Loom
糸
繊維
織機
Thread の問題点
Footprint
スレッドの状態をすべて保存
Context Switch Cost
JVM スタック
オペランドスタック
ローカル変数
ネイティブスタック
Thread 1 Thread n Thread m
… …
JVM Stack Area
Thread 1 Thread n Thread m
… …
JVM Stack AreaPC
Method X
Method Y
Method Z
Thread 1 Thread n Thread m
… …
JVM Stack AreaPC
Method X
Method Y
Method Z
Operand Stack Local Variable
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
2
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
210
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
210
2
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
210
2
スタックから 2 つの数字をポップして掛け算
結果をスタックにプッシュ
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
220
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
220
2
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
220
2
スタックからポップした数値を引数にして
static メソッドをコール
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
2
abs
20
public int calc(int x) {
return 10 * x * Math.abs(x);
}
Runnable task = () -> {
...
int result = calc(2);
...
}
public int calc(int);
0: bipush 10
2: iload_1
3: imul
4: iload_1
5: invokestatic #1 // abs:(I)I
8: imul
9: ireturn
run ※ 実際にはラムダ式なので、run がコールされるわけではないです
calc
Operand Stack Local Variable
2
abs
20
この状態を保存
java.lang.Exception: Stack trace
at java.base/java.lang.Thread.dumpStack(Thread.java:1537)
at java.base/java.lang.Continuation.yield(Continuation.java:396)
at java.base/java.lang.Fiber.maybePark(Fiber.java:597)
at java.base/java.lang.Fiber.parkNanos(Fiber.java:559)
at java.base/java.lang.Fiber.sleepNanos(Fiber.java:1039)
at java.base/java.lang.Thread.sleep(Thread.java:380)
at Test.lambda$new$0(Test.java:14)
at java.base/java.lang.Fiber.lambda$new$0(Fiber.java:198)
at java.base/java.lang.Continuation.enter(Continuation.java:372) Fibers
at java.base/java.lang.Continuation.run(Continuation.java:328)
at java.base/java.lang.Fiber.runContinuation(Fiber.java:366)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1425)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1017)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1666)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1599)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189)
Task
Thread
OS によらずに
JVM が管理するスレッド
Fiber
How to Use Fiber
try (FiberScope scope = FiberScope.open()) {
Runnable task1 = () -> { /* Task */ };
Fiber fiber1 = scope.schedule(task1);
Runnable task2 = () -> { /* Task */ };
Fiber fiber2 = scope.schedule(task2);
}
処理の中断 / 再開 : park/unpark
ただし package private
park/unpark を行う API
java.util.concurrent.locks
Socket/SocketChannel
Thread.sleep
File は現状未対応
現状の制限
ネイティブスタックからは yeild できない
モニタ取得状態で yield できない
キャリアスレッドを pin してしまう
Fiber = Continuation
Scheduling
+
ExecutorService
Default: ForkJoinPool
Continuation Performance
Lazy Copy
Walking the Frames
Freezing oops
Keeping nmethods Alive
Lazy Copy
foo() bar()
baz()
qux()
yeild
Lazy Copy
Stack Continuation Object
タスク中断時
スタックの状態を保存
foo()
bar()
baz()
qux()
Lazy Copy
Stack Continuation Object
タスク中断時
スタックの状態を保存
foo()
bar()
baz()
qux()
Lazy Copy
Stack Continuation Object
タスク再開時
スタックに RB(Read Barrier) を設定し
保存した状態の一部をスタックに戻す
foo()
bar()
baz()
qux()
RB
Lazy Copy
Stack Continuation Object
baz,qux を抜けてスタックが RB まで達したら
残ったスタックの状態を戻す
foo()
bar()
RB
Lazy Copy
Stack Continuation Object
baz,qux を抜けてスタックが RB まで達したら
残ったスタックの状態を戻す
foo()
bar()
Project Panama
Maurizio Cimadamore
Project Panama
Background
Off-Heap Memory Access
Panama
Canal
Native
Java
NativeJava
JNI
NativeJava
Panama
Binding Tool: jextract
Using Panama is Easier,
Safer
and Faster!!
NativeJava
Panama
Binding Tool: jextract
Using Panama is Easier,
Safer
and Faster!!
Missing Link: Memory Access
Off-Heap Memory Access
sun.misc.Unsafe
ByteBuffer
Perfomance Safe Ease of Use
Memory Access API
Key Abstraction
MemorySegment
MemoryAddress
MemoryLayout
メモリ領域
領域のアドレス
領域のメモリレイアウト
struct Point {
int x;
int y;
} pts[5];
x0 y0 x1 y1 x2 y2 x3 y3 x4 y4
Segment
Layout
Address
SequenceLayout seq = MemoryLayout.ofSequent(5,
MemoryLayout.ofStruct(
MemoryLayout.ofValueBits(32).withName(” x” ),
MemoryLayout.ofValueBits(32).withName(” y” ),
)
);
var xHandle = seq.varHandle(int.class,
PathElement.sequenceElement(),
PathElement.groupElement(” x” ));
var yHandle = seq.varHandle(int.class,
PathElement.sequenceElement(),
PathElement.groupElement(” y” ));
var xHandle = seq.varHandle(int.class,
PathElement.sequenceElement(),
PathElement.groupElement(” x” ));
var yHandle = seq.varHandle(int.class,
PathElement.sequenceElement(),
PathElement.groupElement(” y” ));
try (MemorySegment points
= MemorySegment.ofNative(seq)) {
MemoryAddress base = points.baseAddress();
for (long i = 0; i < seq.elementsCount(); i++) {
xHandle.set(base, i, (int) i);
yHandle.set(base, i, (int) i);
}
}
Conclusion
Project Panama
Project Loom
Fiber 軽量スレッド
Continuation 限定継続 機能は検討中
検討すべき項目はまだ多い
jextract 速い 簡単 便利
Memory Access API まだ提案レベル?
Project Loom
櫻庭 祐一
Project Panama

Mais conteúdo relacionado

Mais procurados

Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
MITSUNARI Shigeo
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapi
Ken'ichi Sakiyama
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
Tusyoshi Matsuzaki
 

Mais procurados (20)

C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
Lockfree Queue
Lockfree QueueLockfree Queue
Lockfree Queue
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術
 
あるコンテキストスイッチの話
あるコンテキストスイッチの話あるコンテキストスイッチの話
あるコンテキストスイッチの話
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 
デバドラを書いてみよう!
デバドラを書いてみよう!デバドラを書いてみよう!
デバドラを書いてみよう!
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
 
Reactive Extensions v2.0
Reactive Extensions v2.0Reactive Extensions v2.0
Reactive Extensions v2.0
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapi
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
 
optimal Ate pairing
optimal Ate pairingoptimal Ate pairing
optimal Ate pairing
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
 
20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 

Semelhante a Project Loom + Project Panama

関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。
Yuichi Sakuraba
 

Semelhante a Project Loom + Project Panama (20)

思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
Var handles jjug_ccc_spring_2018
Var handles jjug_ccc_spring_2018Var handles jjug_ccc_spring_2018
Var handles jjug_ccc_spring_2018
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
函数プログラミングの エッセンスと考え方
函数プログラミングのエッセンスと考え方函数プログラミングのエッセンスと考え方
函数プログラミングの エッセンスと考え方
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
JavaOne2015報告会 Java EE アップデート #j1jp
JavaOne2015報告会 Java EE アップデート #j1jpJavaOne2015報告会 Java EE アップデート #j1jp
JavaOne2015報告会 Java EE アップデート #j1jp
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
 
15分でざっくり分かるScala入門
15分でざっくり分かるScala入門15分でざっくり分かるScala入門
15分でざっくり分かるScala入門
 
JavaScript (ECMAScript) 2013
JavaScript (ECMAScript) 2013JavaScript (ECMAScript) 2013
JavaScript (ECMAScript) 2013
 
Slide
SlideSlide
Slide
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 

Mais de Yuichi Sakuraba

Mais de Yuichi Sakuraba (20)

Vector API - Javaによるベクターコンピューティング
Vector API - JavaによるベクターコンピューティングVector API - Javaによるベクターコンピューティング
Vector API - Javaによるベクターコンピューティング
 
Oracle Code One - Java KeynoteとJava SE
Oracle Code One - Java KeynoteとJava SEOracle Code One - Java KeynoteとJava SE
Oracle Code One - Java KeynoteとJava SE
 
Oracle Code One 報告会 Java SE Update
Oracle Code One 報告会 Java SE UpdateOracle Code One 報告会 Java SE Update
Oracle Code One 報告会 Java SE Update
 
今こそStream API入門
今こそStream API入門今こそStream API入門
今こそStream API入門
 
Oracle Code One 報告会 Java SE Update
Oracle Code One 報告会 Java SE UpdateOracle Code One 報告会 Java SE Update
Oracle Code One 報告会 Java SE Update
 
Learn Language 2018 Java Language Update
Learn Language 2018 Java Language Update Learn Language 2018 Java Language Update
Learn Language 2018 Java Language Update
 
Dockerに向けて、Javaもダイエット
Dockerに向けて、JavaもダイエットDockerに向けて、Javaもダイエット
Dockerに向けて、Javaもダイエット
 
What's New in Java
What's New in JavaWhat's New in Java
What's New in Java
 
Migration Guide to Java SE 10, and also Java SE 11
Migration Guide to Java SE 10, and also Java SE 11Migration Guide to Java SE 10, and also Java SE 11
Migration Guide to Java SE 10, and also Java SE 11
 
琥珀色のJava - Project Amber -
琥珀色のJava - Project Amber -琥珀色のJava - Project Amber -
琥珀色のJava - Project Amber -
 
Moving to Module: Issues & Solutions
Moving to Module: Issues & SolutionsMoving to Module: Issues & Solutions
Moving to Module: Issues & Solutions
 
モジュール移行の課題と対策
モジュール移行の課題と対策モジュール移行の課題と対策
モジュール移行の課題と対策
 
Project Jigsawと、ちょっとだけVector API
Project Jigsawと、ちょっとだけVector APIProject Jigsawと、ちょっとだけVector API
Project Jigsawと、ちょっとだけVector API
 
Java SE 9の全貌
Java SE 9の全貌Java SE 9の全貌
Java SE 9の全貌
 
Java SEの現在、過去 そして未来
Java SEの現在、過去 そして未来Java SEの現在、過去 そして未来
Java SEの現在、過去 そして未来
 
Java SE 9 のススメ
Java SE 9 のススメJava SE 9 のススメ
Java SE 9 のススメ
 
Introduction of Project Jigsaw
Introduction of Project JigsawIntroduction of Project Jigsaw
Introduction of Project Jigsaw
 
Encouragement of Java SE 9
Encouragement of Java SE 9Encouragement of Java SE 9
Encouragement of Java SE 9
 
Javaで和暦と元号
Javaで和暦と元号Javaで和暦と元号
Javaで和暦と元号
 
Java in the Past, Java in the Future
Java in the Past, Java in the FutureJava in the Past, Java in the Future
Java in the Past, Java in the Future
 

Project Loom + Project Panama

  • 2. Alan Bateman Richard Bäckman Project Loom Background How to Use Performance
  • 4. Thread の問題点 Footprint スレッドの状態をすべて保存 Context Switch Cost JVM スタック オペランドスタック ローカル変数 ネイティブスタック
  • 5. Thread 1 Thread n Thread m … … JVM Stack Area
  • 6. Thread 1 Thread n Thread m … … JVM Stack AreaPC Method X Method Y Method Z
  • 7. Thread 1 Thread n Thread m … … JVM Stack AreaPC Method X Method Y Method Z Operand Stack Local Variable
  • 8. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn
  • 9. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc
  • 10. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 2
  • 11. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 210
  • 12. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 210 2
  • 13. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 210 2 スタックから 2 つの数字をポップして掛け算 結果をスタックにプッシュ
  • 14. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 220
  • 15. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 220 2
  • 16. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 220 2 スタックからポップした数値を引数にして static メソッドをコール
  • 17. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 2 abs 20
  • 18. public int calc(int x) { return 10 * x * Math.abs(x); } Runnable task = () -> { ... int result = calc(2); ... } public int calc(int); 0: bipush 10 2: iload_1 3: imul 4: iload_1 5: invokestatic #1 // abs:(I)I 8: imul 9: ireturn run ※ 実際にはラムダ式なので、run がコールされるわけではないです calc Operand Stack Local Variable 2 abs 20 この状態を保存
  • 19. java.lang.Exception: Stack trace at java.base/java.lang.Thread.dumpStack(Thread.java:1537) at java.base/java.lang.Continuation.yield(Continuation.java:396) at java.base/java.lang.Fiber.maybePark(Fiber.java:597) at java.base/java.lang.Fiber.parkNanos(Fiber.java:559) at java.base/java.lang.Fiber.sleepNanos(Fiber.java:1039) at java.base/java.lang.Thread.sleep(Thread.java:380) at Test.lambda$new$0(Test.java:14) at java.base/java.lang.Fiber.lambda$new$0(Fiber.java:198) at java.base/java.lang.Continuation.enter(Continuation.java:372) Fibers at java.base/java.lang.Continuation.run(Continuation.java:328) at java.base/java.lang.Fiber.runContinuation(Fiber.java:366) at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1425) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1017) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1666) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1599) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:189) Task Thread
  • 21. How to Use Fiber try (FiberScope scope = FiberScope.open()) { Runnable task1 = () -> { /* Task */ }; Fiber fiber1 = scope.schedule(task1); Runnable task2 = () -> { /* Task */ }; Fiber fiber2 = scope.schedule(task2); } 処理の中断 / 再開 : park/unpark ただし package private
  • 23. 現状の制限 ネイティブスタックからは yeild できない モニタ取得状態で yield できない キャリアスレッドを pin してしまう
  • 25. Continuation Performance Lazy Copy Walking the Frames Freezing oops Keeping nmethods Alive
  • 27. Lazy Copy Stack Continuation Object タスク中断時 スタックの状態を保存 foo() bar() baz() qux()
  • 28. Lazy Copy Stack Continuation Object タスク中断時 スタックの状態を保存 foo() bar() baz() qux()
  • 29. Lazy Copy Stack Continuation Object タスク再開時 スタックに RB(Read Barrier) を設定し 保存した状態の一部をスタックに戻す foo() bar() baz() qux() RB
  • 30. Lazy Copy Stack Continuation Object baz,qux を抜けてスタックが RB まで達したら 残ったスタックの状態を戻す foo() bar() RB
  • 31. Lazy Copy Stack Continuation Object baz,qux を抜けてスタックが RB まで達したら 残ったスタックの状態を戻す foo() bar()
  • 32. Project Panama Maurizio Cimadamore Project Panama Background Off-Heap Memory Access
  • 35. NativeJava Panama Binding Tool: jextract Using Panama is Easier, Safer and Faster!!
  • 36. NativeJava Panama Binding Tool: jextract Using Panama is Easier, Safer and Faster!! Missing Link: Memory Access
  • 38. Memory Access API Key Abstraction MemorySegment MemoryAddress MemoryLayout メモリ領域 領域のアドレス 領域のメモリレイアウト
  • 39. struct Point { int x; int y; } pts[5]; x0 y0 x1 y1 x2 y2 x3 y3 x4 y4 Segment Layout Address
  • 40. SequenceLayout seq = MemoryLayout.ofSequent(5, MemoryLayout.ofStruct( MemoryLayout.ofValueBits(32).withName(” x” ), MemoryLayout.ofValueBits(32).withName(” y” ), ) ); var xHandle = seq.varHandle(int.class, PathElement.sequenceElement(), PathElement.groupElement(” x” )); var yHandle = seq.varHandle(int.class, PathElement.sequenceElement(), PathElement.groupElement(” y” ));
  • 41. var xHandle = seq.varHandle(int.class, PathElement.sequenceElement(), PathElement.groupElement(” x” )); var yHandle = seq.varHandle(int.class, PathElement.sequenceElement(), PathElement.groupElement(” y” )); try (MemorySegment points = MemorySegment.ofNative(seq)) { MemoryAddress base = points.baseAddress(); for (long i = 0; i < seq.elementsCount(); i++) { xHandle.set(base, i, (int) i); yHandle.set(base, i, (int) i); } }
  • 42. Conclusion Project Panama Project Loom Fiber 軽量スレッド Continuation 限定継続 機能は検討中 検討すべき項目はまだ多い jextract 速い 簡単 便利 Memory Access API まだ提案レベル?