先週、@redacted_noah は、@anchorlang の Zero Copy™️ がすべての @solana 開発者のパフォーマンス アルファであるという暴言を送りました ゼロコピーは非常に大きなアカウントにのみ使用されると思っていました なぜ時々それを使っているのかわからないことに気づきました 深く掘り下げることにしました、連👇れて行かせてください
@SuperteamFRANCE @SuperteamJapan まず、なぜゼロコピーデータの解析について話しているのでしょうか? Anchor のデフォルトのデータパーサーは Borsh と呼ばれます。 Anchor命令を呼び出すとき、BorshはアカウントデータをBorsh構造体にコピーします(これについては後で詳しく説明します "ヒープ"と呼ばれるメモリスロットに)
指示にアカウントを含める場合は、次のような形式を使用します。
ゼロコピーを使用する場合、コードは次のようになります。
では、そこで実際に何が起こっているのでしょうか? 最初から明らかではありません! まず、Solana が Rust アプリ データ (ヒープ、スタック、および「ゼロ コピー」スペース) をどのように使用するかを理解する必要があります。
1. スタック: ここには、ローカルデータ型と単純なデータ型が格納されます。 スタックごとに 4KiB のスペースを取得し、各関数呼び出しには独自の 4KiB 割り当てが割り当てられます。 「サイズ X のアドレス XXXXX のスタック フレーム X のアクセス違反」は、最大スタック サイズを超えたときに発生するエラーの種類です。 Anchor では、このエラーの最初の修正は、「ボックス」を使用してデータをスタックから「ヒープ」👇に移動することです
2. Solana のヒープ: プログラムは、デフォルトで 32KB ヒープの BPF VM で実行されます。これは、1 つの呼び出し全体に対する 1 回限りの割り当てです。 ここには、より動的なデータ型 (Vec、String) を格納します Borsh を使用してアカウントを逆シリアル化すると、データがヒープにコピーされ、スペースが急速に消費されます
3. ゼロコピー: 完全なデータ バジェット (大規模なアカウントで多くの CPI) を超えてヒープとスタックをバイパスする必要がある場合は、ゼロ コピーを使用します。 ゼロ・コピーを使用すると、逆シリアル化をスキップして、最初にデータを割り振ったりコピーしたりすることなく、データを操作できます。
ゼロコピーが意味のあるのはどのような場合ですか? 1. 大規模なデータ 2. 多くの CPI を扱う 続けましょう:
1. 大規模なデータ 完全にオンチェーンチェックを実行できるように、ウォレットのリストを自分の状態まで追跡したいとします (これを行う必要がある場合は、マークル ツリー😅を調べてください、これは方法ではありません) 抽選会のように、最終抽選を実行して当選者を選択する前に、各参加者の住所を保存します。 これは簡単に32kbのメモリを超えます。1 人の参加者 = 32 バイトなので、成功して 1000 人の参加者にスペースを割り当てる予定の場合、これはすでにヒープ サイズ全体 (32,000 バイト) を消費しています この状況では、ゼロコピーに移行して制限を回避し、ヒープやスタックの制限に達することなく、はるかに大きなアカウントで作業できるようにします。
直し方? 簡単!どこでもゼロコピーを使用してください。 これは簡単です 👇 (RootEscrow アカウントに #[account("zero_copy")] マクロ属性を追加します) しかし、ゼロコピーには別の課題があり、そもそもAnchorがBorshを選んだ理由は、バイトアライメントです。
バイト アライメントは、すべての Solana 開発者がゼロ コピーを使用するかどうかを理解する必要がある低レベルの手法です 構造体がbytemuckを介してゼロコピーセーフである必要があります(バイトアライメントは正しく処理されないとパニックを引き起こす可能性があります) この*エキサイティングな*トピックに関する別のスレッドをすぐに🔥公開します
それまでの間、私が 9 月中旬から構築し、@colosseum 年のサイファーパンク ハッカソンに参加している製品@legendsdotfunチェックアウトしてください 製品を登録し、有望な新しいチームに賛成票を投じる それぞれのソラナの伝説を輝か🤝せましょう
ヤギに感謝します。 - @redacted_noah - @blockiosaurus - @0xIchigo このライブディスカバリースレッドの校正のために!
5.82K