Parallel Execution (並列実行)

Monadはトランザクションを並列に実行します。最初はこれがEthereumに存在する実行セマンティクスと異なるように思えるかもしれませんが、実際にはそうではありません。MonadのブロックはEthereumのブロックと同じです - トランザクションのリニアに順序付けられたセットです。ブロック内のトランザクションを実行する結果は、MonadとEthereumの間で同一です。

楽観的実行

基本レベルで、Monadは楽観的実行を使用します。これは、Monadがブロック内の前のトランザクションが完了する前にトランザクションの実行を開始することを意味します。時には(常にではありませんが)これにより実行が正しくなくなります。

ブロック内でこの順序である2つのトランザクションを考えてみましょう。

  1. トランザクション1はアカウントAの残高を読み取り更新します(例えば、アカウントBからの転送を受け取ります)。

  2. トランザクション2もアカウントAの残高を読み取り更新します(例えば、アカウントCへの転送を行います)。

これらのトランザクションが並列に実行され、トランザクション2がトランザクション1の完了前に実行を開始した場合、アカウントAの読み取り残高は、順番に実行された場合と異なる可能性があります。これにより実行が不正確になる可能性があります。

楽観的実行がこれを解決する方法は、トランザクション2の実行中に使用された入力を追跡し、それらをトランザクション1の出力と比較することです。もし異なっていれば、トランザクション2が実行中に誤ったデータを使用したことが検出され、正しいデータで再実行する必要があることを意味します。

Monadはトランザクションを並列に実行しますが、各トランザクションの更新された状態は、上記の条件をチェックするために順次統合されます。

関連するコンピュータサイエンスのトピックには、楽観的並行制御(OCC)ソフトウェアトランザクショナルメモリ(STM)があります。

楽観的実行の影響

楽観的実行の単純な実装では、ブロック内の先行するトランザクションが完了するまで、トランザクションを再実行する必要があることが検出されません。その時点で、すべての先行トランザクションの状態更新が統合されているため、トランザクションが2回目の楽観的実行のために失敗することはありません。

状態に依存しないトランザクション実行のステップがあります。例として、署名回復がありますが、これは高価な計算です。この作業は、トランザクションを再実行する際に繰り返す必要はありません。

さらに、統合に失敗したためにトランザクションを再実行する場合、多くの場合、アクセスされるアカウントやストレージは変わりません。この状態はメモリ内にキャッシュされているため、これも再度繰り返す必要のない高価な作業です。

スケジュール設定

楽観的実行の単純な実装は、プロセッサに利用可能なリソースがあるときに次のトランザクションの実行を開始しようとします。ブロック内にお互いに依存する長い「チェーン」のトランザクションが存在するかもしれません。これらのトランザクションを並列に実行すると、多くの失敗が発生する可能性があります。

トランザクション間の依存関係を事前に決定することで、Monadは必要なトランザクションが完了したときにのみトランザクションを実行のためにスケジュールすることで、この無駄な努力を避けることができます。Monadにはこのような予測を試みる静的コードアナライザーがあります。良い場合、Monadは多くの依存関係を事前に予測できますが、最悪の場合、Monadは素朴な実装に戻ります。

今後の作業

トランザクションの再実行を回避する方法は他にもあり、現在検討中です。

Last updated