SlideShare a Scribd company logo
1 of 80
非同期処理の
基礎知識
岩永 信之
今日話すこと
• 非同期処理がらみの良い書き方/悪い書き方
• それがなぜ良い/悪い
• 突き詰めるとCPUやOSレベルの話に
非同期処理の書き方
良い例・悪い例を紹介
先に事例紹介(良い・悪い理由は後ほど)
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
題材
• スレッドのコスト
• スレッド プール
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
題材
• CPU-boundとI/O-bound
• I/O完了ポート
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
題材
• 競合が起きる理由
• lock
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
題材
• スレッド並列
• 並列化しやすいアルゴリズム
イベントの実装(前置き)
event EventHandler Disposed; 自動実装イベント
event EventHandler Disposed
{
add { _disposed += value; }
remove { _disposed -= value; }
}
private EventHandler _disposed;
こんな意味合いのコードに対し
て、
「スレッド安全」が求められる
(C#の規格上そう定めてある)
C#のイベント
「自動実装」の結果 (意味的には)
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
lock-free※アルゴリズム
※ lockを使わずに競合を避けること
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
題材
• interlocked命令
• lock-freeアルゴリズム
lock-free※アルゴリズム
※ lockを使わずに競合を避けること
基礎
今の事例はいったん置いておいて
CPUとかOSレベルの話を
CPU
まず、CPUの動作について
CPU = 演算回路+記憶領域
ALU
メイン・メモリ
データを格納
高速・小容量
加減乗除などの
演算を実行†
データを格納
低速・大容量
† arithmetic logic unit
演算回路記憶領域
CPU = 演算回路+記憶領域
ALU
メイン・メモリ
記憶領域には階層がある
高速小容量 ⇔ 低速大容量
演算回路と直接つながってるのは、
1番高速で、1番小容量の記憶
CPUの動作例
• 高級言語的に1ステートメントでも…
ALU
メイン・メモリ
++count;
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
C#
CPU命令
コンパイル
CPUの動作例
① 読み込み
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
CPUの動作例
② 演算
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
+1
++count;
C#
CPU命令
コンパイル
CPUの動作例
③ 書き出し
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
CPUの動作例
③ 書き出し
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
ポイント
• 単純な処理でも複数命令からなる
• 読み込み、演算、書き出し
• 上から順に逐次実行
注意: 読み込みの原子性※
ALU
メイン・メモリ
64bit データ
ALU
メイン・メモリ
データ64bit
※ atomicity: 不可分性。中途半端な不正な状態を起こさないこと
64bit CPUの場合 32bit CPUの場合
1命令完結 2命令必要
命令と命令の間に割り込まれると
データが半分しか読まれてない状態になる
割り込み
CPUと、CPUの外の世界(ハードウェア割り込み)
特権モード(ソフトウェア割り込み)
CPUの外の世界
• 当然、CPUだけでは何もできない
ALU
メイン・メモリ
CPU 周辺機器
割り込み信号
割り込み
• 外部ハードウェアから「割り込み信号」が来る
• 信号を受け取ると、実行中の処理を止めて、いった
ん別処理をする
命令列
別の処理
外部ハードウェアから
の信号を受け取って、
処理を中断
再開
mov eax, [04D74010h]
inc eax
mov [04D74010h], eax
……
割り込みタイミング
• 割り込みはどこでかかるかわからない
mov eax, [04D74010h]
inc eax
mov [04D74010h], eax
……
ここで割り込まれる
かもしれないし
ここも
ここも
ここもありえる
ハードウェア タイマー
• 一定間隔で割り込み信号を送ってくるハード
ウェアがある
• スレッドで使う(詳細は後述)
命令列
ハードウェアタイマー
割り込み
割り込み
割り込み
…
別の処理
別の処理
別の処理
ソフトウェア割り込み
• 割り込み命令
命令列
別の処理
自分自身で割り込みを
起こせる命令がある
再開
割り込み発生命令
……
モード切り替え
• 何に使うかというと、モード切り替え
命令列
別の処理割り込み発生命令
……
通常のセキュリティ
レベルで動作
特権的なセキュリティ
レベルで動作
異なるモードで動作
特権モード
ユーザー モード
• 一般のプログラ
ムに認められる
セキュリティ レ
ベル
• アクセスできる
メモリに制限が
ある
特権モード※
• OSが使うセキュ
リティ レベル
• 制限がかからな
い
モード移行にはそれなりのコストが発生
※ OSのカーネルが使うんで、カーネル モード(kernel mode)ともいう
CPUの高度化
キャッシュ メモリ
マルチコアCPU
• 記憶領域の階層は多段
メイン メモリ
2次キャッシュ メモリ
キャッシュ
ALU
キャッシュ メモリ
高速
小容量
低速
大容量
速度差が大きすぎる
キャッシュ1段ごとに1桁くらい遅い
• 記憶領域の階層は多段
メイン メモリ
2次キャッシュ メモリ
キャッシュ
ALU
キャッシュ メモリ
高速
小容量
低速
大容量
このサイズに収まる範囲で
読み書きする分には高速
広範囲にデータを読み書き
すると、低速なメモリへの
読み書きが発生
• コアごとにキャッシュ持ってたり
メイン メモリ
2次キャッシュ メモリ
マルチコア
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
• コアで同じデータを読み書きすると
メイン メモリ
2次キャッシュ メモリ
マルチコア
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
同じブロックを読み書
きしているつもりでも 実際には別の場所にある
1段下(低速)に書き戻されて
ないと正しい値が取れない = 1桁遅い
• 非均一な読み書き速度
NUMA※
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
※ non-uniform memory access: 非均一なメモリアクセス
メモリ ノード1 メモリ ノード2 メモリ ノード3
高速
アクセスはできる
ものの、低速
• 非均一な読み書き速度
NUMA※
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
※ non-uniform memory access: 非均一なメモリアクセス
メモリ ノード1 メモリ ノード2 メモリ ノード3
高速
アクセスはできる
ものの、低速
ポイント
• コアをまたいだデータ読み書きは
かなり低速
スレッド
マルチタスク
CPUのシェア
マルチタスク
• コンピューター内で複数のタスクが同時に動作
• CPUコア数に制限されない
タスク1 タスク2 タスク3 …
タスクの動作期間
実際にCPUを使って
動いている期間
1つのCPUコアを複数の
タスクがシェアしてる
問題は
• どうやって他のタスクにCPUを譲るか
• 誰がどうスケジューリングするか
2種類のマルチタスク
† preemptive: 専買権を持つ、横取りする
※cooperative
• ハードウェア タイマーを使って強制割り込み
• OSが特権的にスレッド切り替えを行う
• ○利点: 公平 (どんなタスクも等しくOSに制御奪われる)
• ×欠点: 高負荷 (切り替えコストと使用リソース量が多い)
プリエンプティブ†
• 各タスクが責任を持って終了する
• 1つのタスクが終わるまで次のタスクは始まらない
• ○利点: 低負荷
• ×欠点: 不公平 (1タスクの裏切りが、全体をフリーズさせる)
協調的※
なのでスレッドはこっち
これが致命的
ただ、問題はこれ
スレッドを立てるコスト※
• スレッドに紐づいたデータ
• カーネル ステート: 1kBくらい
• ローカル スタック: 1MBくらい
• イベント発生
• Thread Attached/Detachedイベント
※ Windowsの場合
スレッド切り替えコスト
• 直接的なコスト
• 特権モードへの移行・復帰
• レジスターの保存・復元
• 次に実行するスレッドの決定
• スレッドの状態を入れ替え
• 間接的なコスト
• キャッシュ ミス
どれも性能への
インパクト大きい
スレッドは高コスト
• 細々としたタスクを大量にこなすには向かない
for (int i = 0; i < 1000; i++)
{
var t = new Thread(Worker);
t.Start();
}
大量の処理をスレッド実行
リソース消費大
切り替え頻発
…
スレッド プール
• スレッドを可能な限り使いまわす仕組み
• プリエンプティブなスレッド数本の上に
• 協調的なタスク キューを用意
スレッド プール
キュー
タスク1
タスク2
…
数本※のスレッ
ドだけ用意
空いているスレッドを探して実行
(長時間空かない時だけ新規スレッド作成)
新規タスク
タスクは一度
キューに溜める
※ 理想的にはCPUのコア数分だけ
スレッド プールの性能向上
• Work Stealing Queue
• lock-free実装(後述)なローカル キュー
• できる限りスレッド切り替えが起きない作り
ローカル
キュー1
ローカル
キュー2
スレッド1 スレッド2
グローバル
キュー
①
スレッドごとに
キューを持つ
まず自分用の
キューからタスク実行
②
ローカル キュー
が空のとき、
他のスレッドから
タスクを奪取
スレッド プールの性能向上
• Work Stealing Queue
• lock-free実装(後述)なローカル キュー
• できる限りスレッド切り替えが起きない作り
ローカル
キュー1
ローカル
キュー2
スレッド1 スレッド2
グローバル
キュー
①
スレッドごとに
キューを持つ
まず自分用の
キューからタスク実行
②
ローカル キュー
が空のとき、
他のスレッドから
タスクを奪取
ポイント
• スレッドは高コスト
• Threadくらすはこっち
• スレッド プールの利用推奨
• Taskクラスはこっち
I/O完了ポート
外部ハードウェアからの応答を待つ
CPUの外の世界は遅い
• 実行速度が全然違う
ALU
メイン・メモリ
CPU 周辺機器
数千~
下手すると数万、数億倍遅い
2種類の負荷
• CPU-bound (CPUが性能を縛る)
• マルチコアCPUの性能を最大限引き出したい
• UIスレッドを止めたくない
• I/O-bound (I/O※が性能を縛る)
• ハードウェア割り込み待つだけ
• CPUは使わない
• スレッドも必要ない
※ Input/Output: 外部ハードウェアとのやり取り(入出力)
I/O完了待ち
• I/O-boundな処理にスレッドは不要
あるスレッド
要求
応答
この間何もしないのに
スレッドを確保し続け
るのはもったいない
I/O完了ポート※
• スレッドを確保せずI/Oを待つ仕組み
• コールバックを登録して、割り込みを待つ
• コールバック処理はスレッド プールで
スレッド プール
タスク1
タスク2
…
※ I/O completion port
あるスレッドアプリ
I/O完了ポート
ハードウェア
I/O開始 I/O完了
コールバック
登録
コールバック登録後、
すぐにスレッド上での
処理を終了
割り込み信号
I/O完了ポート※
• スレッドを確保せずI/Oを待つ仕組み
• コールバックを登録して、割り込みを待つ
• コールバック処理はスレッド プールで
スレッド プール
タスク1
タスク2
…
※ I/O completion port
あるスレッドアプリ
I/O完了ポート
ハードウェア
I/O開始 I/O完了
コールバック
登録
コールバック登録後、
すぐにスレッド上での
処理を終了
割り込み信号
ポイント
• I/O-boundな処理にスレッドを使っちゃダメ
• I/O用の非同期メソッドが用意されてる
(内部的にI/O完了ポートを利用)
事例に戻って
良い例・悪い例の理由
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
おさらい
• Threadクラス
• Windowsの生スレッド
• = プリエンプティブなマルチタスク
• 当然重たい
• 特権モード移行、レジスター退避、…
• Taskクラス
• スレッド プールを利用
• 必要な分だけスレッド使う
推奨
スレッドは生で使
うものじゃない
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
おさらい
• I/O-boundな処理のためにスレッドを専有し
ちゃダメ
• I/O完了ポート使う
• ハードウェアからの割り込みをイベント処理
• 標準ライブラリの~Async系のメソッドはこれを利
用
非推奨
Task.Run(() => r.ReadToEnd());
推奨
r.ReadToEndAsync();
おまけ: SleepよりもDelay
Task.Delay((int)(x * Scale))
.ContinueWith((_, state) =>
{
sorted.Enqueue((double)state);
}, x);
var t = new Thread(state =>
{
var value = (double)state;
Thread.Sleep((int)(value * Scale));
sorted.Enqueue(value);
});
t.Start(x);
スレッドを立ててから
Thread.Sleepで休止
Task.Delayで休止
×悪い例
○良い例
• 何もしないのにスレッド
を確保し続ける
• タイマー利用
(ハードウェア割り込み)
• スレッドを確保しない
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
おさらい
• スレッドはハードウェア タイマーの割り込み
を使ってる
• 割り込みはいつかかるかタイミング不定
• 単純なコードでも、CPUレベルでは複数命令
++count;
C# CPU命令コンパイル
① 読み mov eax, [04D74010h]
② 計算 inc eax
③ 書き mov [04D74010h], eax
競合
• 複数のスレッドで同じ場所を読み書きすると…
シングル スレッド マルチ スレッド
読み
計算
書き
読み
計算
書き
読み
計算
読み
計算
読み
計算
書き
読み
計算
書き
……
……
switch
switch
書き込み終わる前にスレッド
が切り替わることがある
• 計算前の値を再度読んじゃう
だいぶ昔の計算結果で上書き
• 別スレッドで計算してた分が消える
lock
• 競合回避のためにlock (鍵)をかける
switch
switch
lock獲得
lock解放
lock獲得
獲得失敗
他のスレッドがlock獲得
しようとすると失敗する
その場でいったんスレッ
ド実行を停止
読み
計算
書き
lock
• 競合回避のためにlock (鍵)をかける
switch
lock獲得
lock解放
獲得~解放の間は、同時に2つ以上
のスレッドで実行されなくなる読み
計算
書き
lock獲得
lock解放
読み
計算
書き
lockの仕組み
• OSのスレッド スケジューラーに依頼
• lockがかかっていると、スケジューラーがスレッド
実行を止める
• 特権モードが必要
• 無駄にスレッド切り替えが増える
高コスト
switch
switch
lock獲得
lock解放
lock獲得
獲得失敗
読み
計算
書き
スレッド切り替えも高コスト
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
おさらい
• lockは高コスト
• 特権モードが必要
• 無駄なスレッド切り替え発生
• スレッド間のデータ共有は高コスト
• (特に書き込み)
• キャッシュからメイン メモリへの書き戻し
• コアごとのキャッシュへの伝搬
• NUMA (非均一メモリ アクセス)
スレッドごとの独立性
• 性能を求めるなら
• スレッド間での同じ場所の読み書きをなくす
• Parallelクラスにはそのためのオーバーロードあり
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
スレッドごとに別々に+1
最後にスレッドごとの結果を足す
気を付けるポイント
• 独立に計算できないと、並列化の利益少ない
• 順序依存とかがあると無理
交換法則、結合法則が大事
これが成り立たない演算は
並列化に向かない
さっきの++countループの例だと
この辺りに気を使って
アルゴリズム考える必要あり
和を2つに分解
(分解しても計算結果が一緒)
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
lock-free※アルゴリズム
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
※ OS機能(特権モード必要)のlockを使わずに競合を避けること
おさらい
• lockは高コスト(再)
• 特権モードが必要
• 無駄なスレッド切り替え発生
• 旧実装はlock
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
add { lock(this) { _disposed += value; } }
※ lock(this)は性能面以外にも問題あり
旧コードはいろんな意味でレガシー
※
新実装
• lockなしで競合回避するためのアルゴリズム
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, valu
disposed = Interlocked.CompareExchange(ref _disposed, handle
}
while (disposed != handler2);
}
こいつがポイント
Interlocked
• CPUには「必ず原子的※に実行する保証付き」
な命令がいくつかある(interlocked命令)
• .NETの場合、Interlockedクラスを利用
※ atomic: 不可分な。途中で他のスレッドなどに割り込まれない保証
var count = 0;
Parallel.For(0, num, i =>
{
Interlocked.Increment(ref count);
});
例: 原子性保証付きのインクリメント
挙動的にはlock付きの++countと同じ
lockとinterlocked命令
• lockはOS機能
• 特権モード移行が必要
• スレッド切り替えの機会を増やす
• 任意の処理をlockできる
• Interlocked命令は単なるCPU命令
• 特権モード不要
• lockよりはだいぶ低コスト
• とはいえ、普通の命令と比べると1桁くらいは遅い
• 単純な処理しか用意されてない
• インクリメントとか
CAS※
• 特に重要なのがCAS命令
• .NET的にはInterlocked.CompareExchangeメソッド
※ compare and swapの略。比較しながら交換
Intel CPUの命令名称的には compare exchange
int CompareExchange(ref int loc, int value, int comp)
{
int ret = loc;
if (ret == comp)
loc = value;
return ret;
}
↓こういう意味のコードを原子性保証付きで実行する命令
比較しながらの値の交換
CAS
• 何が重要かというと
• 競合が起きたことを検知できる
• 「競合を避ける」よりははるかに低コスト
int CompareExchange(ref int loc, int value, int comp)
{
int ret = loc;
if (ret == comp)
loc = value;
return ret;
} 競合してたら元のlocとは違う値が返る
新実装がやってること
• 競合が見つかったらやりなおし
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, valu
disposed = Interlocked.CompareExchange(ref _disposed, handle
}
while (disposed != handler2);
}
競合検知しながらの交換
競合してたら最初からやりなおし
いわゆる「楽観的排他制御」
eventの+=が競合することはほとんどないので、ほぼ1発
注意
• この手のlock-freeアルゴリズムは書くの大変
• 書いたはいいけど、テストが大変
• 普通はライブラリまかせ
• Taskクラス(が使ってるスレッド プール)
• System.Collections.Concurrent名前空間内のクラス
• eventの自動実装(C# 4.0以降)
内部的にlock-free実装なものの例:
まとめ
• スレッドは高コスト
• スレッド プール(Taskクラス)推奨
• I/O-boundな処理にスレッド不要
• ~Asyncメソッドの利用推奨
• 競合
• lockが必要
• できればlockも避ける
• そもそもスレッド間でデータ共有しないアルゴリズム
• lock-freeアルゴリズム(interlocked命令)
• 競合を避けるよりは、検知してやり直しの方が低コスト

More Related Content

What's hot

.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理KageShiron
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
できる!並列・並行プログラミング
できる!並列・並行プログラミングできる!並列・並行プログラミング
できる!並列・並行プログラミングPreferred Networks
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Etsuji Nakai
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解MITSUNARI Shigeo
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてalwei
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話Yoshitaka Kawashima
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについてmametter
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介MITSUNARI Shigeo
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化Gosuke Miyashita
 

What's hot (20)

Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
できる!並列・並行プログラミング
できる!並列・並行プログラミングできる!並列・並行プログラミング
できる!並列・並行プログラミング
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
CPUの同時実行機能
CPUの同時実行機能CPUの同時実行機能
CPUの同時実行機能
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについて
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化
 

Similar to 非同期処理の基礎

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~CHY72
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3DKouji Hosoda
 
これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)なおき きしだ
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweightgintenlabo
 
Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Sho Shimauchi
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScriptbleis tift
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
how-calculate-cluster-coefficience
how-calculate-cluster-coefficiencehow-calculate-cluster-coefficience
how-calculate-cluster-coefficienceNorihiro Shimoda
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キューYuto Takei
 
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワークisaac-otao
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算kunihikokaneko1
 

Similar to 非同期処理の基礎 (20)

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
 
これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweight
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
how-calculate-cluster-coefficience
how-calculate-cluster-coefficiencehow-calculate-cluster-coefficience
how-calculate-cluster-coefficience
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
 
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
 
jenkinsで遊ぶ
jenkinsで遊ぶjenkinsで遊ぶ
jenkinsで遊ぶ
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
Xtext 紹介
Xtext 紹介Xtext 紹介
Xtext 紹介
 
20120721_ishkawa
20120721_ishkawa20120721_ishkawa
20120721_ishkawa
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算
 

More from 信之 岩永

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話信之 岩永
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話信之 岩永
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理信之 岩永
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム信之 岩永
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型信之 岩永
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)信之 岩永
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1信之 岩永
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方信之 岩永
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6信之 岩永
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に信之 岩永
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform信之 岩永
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3信之 岩永
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 

More from 信之 岩永 (20)

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
 
Modern .NET
Modern .NETModern .NET
Modern .NET
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 

Recently uploaded

論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Hiroshi Tomioka
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (11)

論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 

非同期処理の基礎