1

GNU Octave でスパースバイナリマトリックスを操作しようとしていますが、予想よりも多くのメモリを使用しており、関連するスパース マトリックス関数が意図したとおりに動作しません。MATLAB での予想よりも高いスパース行列ストレージに関するこの質問が表示されます。これは、この行列がさらに多くのメモリを消費する必要があることを示唆していますが、この状況の一部 (のみ) を説明するのに役立ちました。

まばらなバイナリ マトリックスの場合、Octave に値の配列を格納しないようにする方法がわかりません(値は常に暗黙的1に格納されるため、格納する必要はありません)。これはできますか?Octave は常に値配列のためにメモリを消費するようです。

状況を示す簡略化された例: ランダムな疎行列を作成し、それを「バイナリ」に変換します。

mys=spones(sprandn(1024,1024,.03)); nnz(mys), whos mys

状況を示します。ストレージクラスspones()の配列を作成し、すべてdoubleのインデックスが 32 ビット (つまり、

TotalStorageSize - rowIndices - columnIndices == NumNonZero*sizeof(double)
-- これらの値 (すべて1s を s としてdouble) を不必要に格納すると、この 3% 疎オブジェクトによって消費される合計メモリの半分以上になります。

この質問を作成している間にこれを(あまりにも長く)いじった後、いくつかの部分的な回避策を発見したので、継続性のために質問の一部を「自己回答」(のみ)します(うまくいけば)が、わかりませんでした主な質問に対する適切な答えを出してください:

Octave で効率的に格納された ("no-/implicit-values") バイナリ マトリックスを作成するにはどうすればよいですか?

ストレージ形式に関する追加の背景情報は次のとおりです...

Octave のドキュメントによると、スパース行列のストレージ形式はCompressed Sparse Column (CSC)という形式を使用します。これは、次の配列を格納することを意味しているようです (前述の SO answerを拡張し、正規のYale 形式 labels列優先順の微調整を使用):

  • ( A)、ストレージ クラス サイズのゼロ以外の数 (NNZ) エントリ。
  • 行番号( IA)、インデックス サイズの NNZ エントリ (うまくいけばint64、しかし多分int32);
  • 各列の開始( JA)、列数にインデックス サイズの 1 エントリを加えたもの)

この場合、バイナリのみのストレージの場合、配列 ( ) の格納を完全に回避する方法があることを願っていますAが、それがわかりません。

4

1 に答える 1

1

完全な開示:上記のように、この質問を作成しているときに、メモリ使用量を減らすための回避策を発見したので、ここで「自己回答」していますが、それでも完全に満足できるものではないので、些細で肥大化した不要な値の配列を使用せずに、スパースバイナリマトリックスのストレージに対するより良い実際の答えをまだ聞いています...

この場合、数値に似た値からバイナリに似た値を取得し、メモリ使用量を削減するlogical(X)には、 によって作成された「論理」ストレージを使用します。たとえば、上からの構築、

logicalmys = logical(mys);

sparse bool matrixより少ないメモリを使用する を作成します ( values 配列のlogical8 バイトではなく1 バイト)。double

whosを使用して情報にさらに情報を追加するとwhos_line_format、状況が明らかになります。デフォルトの文字列には、7 つのプロパティのうち 5 つが含まれます (詳細については、ドキュメントを参照してください)。フォーマット文字列を使用しています

whos_line_format(" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:8; %e:10; %t:20;\n")

「要素」と「タイプ」(「クラス」とは異なる)の表示を追加します。

それで、whos mys logicalmys次のようなものを示します

 Attr Name            Size      Bytes Class      Elements                 Type
 ==== ====            ====      ===== =====      ========                 ==== 
      mys          1024x1024   391100 double        32250        sparse matrix
      logicalmys   1024x1024   165350 logical       32250   sparse bool matrix

したがって、これは と の違いを示していsparse matrixますsparse bool matrix。ただし、によって消費される合計メモリlogicalmysは、実際に NNZ ブール値 (1 バイト) の配列を格納することと一致します。つまり、次のようになります。

  • totalMemory から rowIndices を引いて columnOffsets を引くと NNZ バイトが残ります。

数字で、

  • 165350 - 32250*4 - 1025*4 == 32250.

したがって、まだ 32250 個の要素を保存していますが、そのすべてが1. さらに、要素の 1 つ1をゼロに設定すると、報告されるストレージが減少します。しばらくの間、次のことを試してみてください: などの非ゼロ要素を選択し(42,1)、次にそれをゼロにします:logicalmys(42,1) = 0;それwhosから!

私の願いは、これが正しいことであり、これが興味を持っているかもしれない人々にとっていくつかのことを明確にすることです. コメント、修正、または実際の回答を歓迎します!

于 2014-06-26T19:19:10.830 に答える