Step0. これは何ですか?
C++23標準ライブラリに追加された 多次元配列ビューstd::mdspan を利用して、リモートマシン上の仮想メモリに対する 透過的なメモリアクセス(Read/Write) を実現するデモコードを書いたお話です。
つまり…どういうことだってばよ?
Step1. RESTful malloc Server実装
下準備として、RESTful APIを提供するmalloc Serverを実装します。簡単のためGo言語を利用しました。あっ、石を投げつけないで...
malloc ServerではHTTPリクエストを介したメモリ操作をサポートします。
- メモリブロックの確保(
malloc操作) - メモリブロックの解放(
free操作) - メモリアドレスへの1バイト書き込み(Write操作)
- メモリアドレスからの1バイト読み取り(Read操作)
つまりC標準ライブラリ提供のmalloc関数/free関数相当の動作と、アドレス値を介したメモリ読み書き操作をWeb APIとして提供するサーバアプリケーションです。何を言っているか理解できない?ご安心ください、私は正気です。
$ ADDR=$(curl -X POST -s http://localhost:8080/memory/malloc -d '{"size":10}' | jq .addr)
$ echo $ADDR
$ curl -X PUT -s http://localhost:8080/memory/$ADDR -d '{"val":123}'
$ curl -X GET -s http://localhost:8080/memory/$ADDR | jq .val
$ curl -X POST -s http://localhost:8080/memory/free -d "{\"addr\":$ADDR}"
Step2. std::mdspan AccessorPolicy実装
C++標準ライブラリヘッダ <mdspan> で提供される std::mdspan<T,E,L,A>クラステンプレート は、第4テンプレート引数A(AccessorPolicy)を介してメモリアクセス戦略をカスタマイズできます。
メモリ書込/読取操作をmalloc ServerへのAPI呼び出しに変換する独自ポリシークラスmc::RemoteMemoryAccessor<T>として実装し、クライアントコードからはリモートホストへのWeb API呼び出しを完全に隠蔽できます。下記コードのarr[i] = i;やstd::cout << arr[i]ではHTTPリクエストが発生しますが、ソースコード上はあたかも通常メモリアクセスのように記述しています。
繰り返しますが、私は正気です...よね?
// allocate remote memory on malloc-server
mc::RemoteMemory rmem;
mc::RemoteAddress addr = rmem.malloc(sizeof(int) * N);
// create `mdspan` as a view of remote memory
using extents_type = stdx::dextents<size_t, 1>; // 1D-array[dynamic]
using mapping_type = stdx::layout_right::mapping<extents_type>;
using accessor_type = mc::RemoteMemoryAccessor<int>;
stdx::mdspan arr{addr, mapping_type{extents_type{N}}, accessor_type{rmem}};
// write to remote memory
for (size_t i = 0; i < arr.extent(0); i++) {
arr[i] = i;
}
// read from remote memory
for (size_t i = 0; i < arr.extent(0); i++) {
std::cout << (i ? " " : "") << arr[i];
}
当然のことながら、本記事の内容は本来想定される AccessorPolicy 利用ケースからは程遠いと思われます。正しい使い方は次期C++26標準ライブラリで追加される下記クラステンプレート群を参照ください。
Acknowledgements