Share via


Memory2D<T>

Memory2D<T> は、型 Memory<T> の機能をミラーする型であり、2D のメモリの場所を表すために使用できるという違いがあります。 これは非常に高い柔軟性を持ち、ND 配列 (1D、2D、3D 配列を明示的にサポートします) や Memory<T> インスタンスなど、さまざまな型をラップできます。 この型は、Memory<T>Span<T> と合わせて使用されるのと同様に、Span2D<T> と合わせて使用されることが想定されています。 これら 2 つの型の主な相違点とユース ケース シナリオの詳細については、こちらのドキュメント ページで確認できます。

プラットフォーム API:Memory2D<T>Span2D<T>ReadOnlyMemory2D<T>

しくみ

Memory2D<T> 型は、ラップされたオブジェクトへの参照、高さと幅のパラメーター、特殊なピッチ パラメーターを介して、マップされた 2D メモリ領域を内部的に追跡します。 高さと幅は 2D メモリ領域内の行と列の長さを表し、ピッチは各行の末尾と次の行の開始点の間のオフセットを表します。

この構成を表す簡単な図を次に示します (グリッドの "XX" セルは、ターゲットの 2D メモリ領域に属する項目を表します)。

//                _____________________stride_____...
//  reference__  /________width_________  ________...
//             \/                       \/
// | -- | -- | |- | -- | -- | -- | -- | -- | -- | -- |_
// | -- | -- | XX | XX | XX | XX | XX | XX | -- | -- | |
// | -- | -- | XX | XX | XX | XX | XX | XX | -- | -- | |
// | -- | -- | XX | XX | XX | XX | XX | XX | -- | -- | |_height
// | -- | -- | XX | XX | XX | XX | XX | XX | -- | -- |_|
// | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
// | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
// ...__pitch__/
// ...________/

この構成では、Memory2D<T> が既存のバッファーを 2D メモリ領域にマップすることで、不連続なバッファーを "仮想的な" 2D メモリの場所として表すことが可能になるため、非常に高い柔軟性が実現されます。 たとえば、以下に Memory2D インスタンスがマップできるバッファーの型の例をいくつか示します。

  • 行優先順に 2D メモリ領域としてマップされる 1D T[] 配列。
  • Memory2D<T> インスタンスに直接マップされる 2D T[,] 配列。
  • 特定の深度スライス (レイヤー) を表す Memory2D<T> インスタンスを含む 3D T[,,] 配列。

Memory<T> 型は、標準 Memory<T> が実装する API サーフェスの大部分を含め、多くのユーティリティ メソッドも公開しています。 たとえば、仮想的な 2D メモリの場所で 2D スライス操作を容易に実行できるようにする Slice(int, int) メソッドが含まれており、Memory2D<T> インスタンスは、要求された結果に対応する適切なメモリ領域にマッピングをシフトするために必要なパラメーターを内部的に自動調整します。

構文

2D 配列から Memory2D<T> インスタンスを作成する方法を次に示します。

int[,] array =
{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

Memory2D<int> memory = array;

// The memory directly maps the 2*3 array here

Memory2D<int> slice = memory.Slice(0, 1, 2, 2);

// We create a slice from row 0 and column 1, of size 2*2

int[,] copy = slice.ToArray();

// { 2, 3 }
// { 5, 6 }

// If on a supported runtime, we can also slice using a range

Memory2D<int> test = memory[.., ..2];

// { 1, 2 }
// { 4, 5 }
// { 7, 8 }

Span2D<int> span = memory.Span;

// We can use the span to perform operations on the underlying
// data for the memory instance. All the available APIs are
// documented in the docs about the Span2D<T> type.

ReadOnlyMemory2D<T>

ReadOnlyMemory2D<T>Memory2D<T> の関係は、ReadOnlyMemory<T>Memory<T> の関係と同じです。 これは、まったく同じ機能 (ラップされたメモリ領域の内容の変更を伴う API は除く) を公開し、任意の 2D メモリの場所への読み取り専用ビューを提供します。 この型の動作の詳細については、上記の Memory2D<T> 型の段落を参照してください。

単体テスト」では、さらに他の例を見つけることができます。