MATLABのコピーオンライト(レイジーコピー)メカニズムを使用して、セル配列内の複数のセルから同じ大きな行列をリンクしようとしたときに、正しく実行されているかどうかを確認する方法があるかどうか疑問に思っています。
例えば:
img = randn(500);
[dx,dy] = gradient(img);
S = cell(2,2);
S{1,1} = dx.^2;
S{2,2} = dy.^2;
S{1,2} = dx.*dy;
S{2,1} = S{1,2}; % should be a reference, as long as not modified
しかし、の出力を見てくださいwhos
:
>> whos
Name Size Bytes Class Attributes
S 2x2 8000448 cell
dx 500x500 2000000 double
dy 500x500 2000000 double
img 500x500 2000000 double
私はS
8MBではなく6MBを占めることを望んでいました。
プログラムに間違いがなく、それらの2つのセルが最後に同じ配列を参照していることを確認する方法はありますか?
私はその機能を知っていますmemory
が、残念ながらWindowsプラットフォームでしか機能しません(私はMacOSを使用しています)。
編集:
回答を編集する前に、予期しない動作をし、その署名が異なるバージョンのMATLAB間で安定していない、文書化されていない関数を使用したので、ここで@CrisLuengoの回答の拡張バージョンを提供しました。
ハッシュマップを使用して、データ要素とそれに関連するmxArray
の一意のアドレスを再帰関数check_shared
に格納し、データのサイズを取得できます。ここでは、セル内の共有ステータスを確認できますが、セルの外部にあり、セル要素と同じアドレスを持つ要素を確認することはできません。*
#include "mex.h"
#include <unordered_map>
typedef std::unordered_map<void *,const mxArray *> TableType;
TableType check_shared(const mxArray* arr, TableType table = TableType())
{
switch (mxGetClassID(arr)) {
case mxCELL_CLASS:
for(int i = 0; i < mxGetNumberOfElements (arr); i++) {
table = check_shared(mxGetCell (arr,i), std::move(table));
}
break;
case mxSTRUCT_CLASS:
for (int i = 0; i < mxGetNumberOfFields (arr); i++) {
for (int j = 0; j < mxGetNumberOfElements (arr); j++) {
table = check_shared(mxGetFieldByNumber (arr, j, i), std::move(table));
}
}
break;
case mxVOID_CLASS:
case mxFUNCTION_CLASS:
case mxUNKNOWN_CLASS:
return table;
}
if (!mxIsEmpty (arr)) {
void* data = mxGetData(arr);
table[data] = arr;
}
return table;
}
uint64_t actual_size(const TableType& table)
{
uint64_t sz = 0;
for (const auto& entry : table) {
const mxArray * arr = entry.second;
sz += mxGetElementSize (arr) * mxGetNumberOfElements (arr);
}
return sz;
}
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
TableType table = check_shared(prhs[0]);
plhs[0] = mxCreateNumericMatrix(1,1, mxUINT64_CLASS, mxREAL );
uint64_t* result = static_cast<uint64_t*>(mxGetData (plhs[0]));
result[0] = actual_size(table);
}
(*)などの基本的なデータ型cell
、struct
および数値配列がサポートされています。不明なデータ構造とclassdefオブジェクトの場合、関数はゼロを返します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加