2016-09-24 6 views
3

julia --track-allocation=userのメモリ割当レポートで割り当ての最大値がこの関数である:ジュリア、関数内のループでメモリ割り当てが行われるのはなぜですか?

 - function fuzzy_dot_square(v::Array{Int64, 1}) 
     -  dot_prod = zero(Int64) 
7063056168  for i::Int64 in 2:28 
     0   dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i+28])#/4 # no "top" pixel 
     -  end 
     0  for i in 29:(28*27) # compiler should literate 28*27 
     0   dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28] + v[i+28])#/5 # all pixels 
     -  end 
     0  for i in (28*27):(28*28 - 1) 
     0   dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28])#/4 # no "bottom" pixel 
     -  end 
     - 
     0  return dot_prod 
     - end 

- それは28ピクセル画像28を表す、ベクトルの「ファジードット積」正方形であり(既知MNIST数字画像のデータセット)。

なぜ割り当てはそこで行われますか? 私が理解する限り、dot_prodは割り当てられる唯一のものです。 しかし...

ための最初のレポートポイントはまた、私はとREPLでそれを再現しようとした:

v = Array{Int64,1}(1:100) 
dot_prod = zero(Int64) 
@allocated for i in 2:28 
    dot_prod += v[i] 
end 

- と私は@allocated for ...でエラーを以下の取得:

ERROR: UndefVarError: dot_prod not defined 
in macro expansion at ./REPL[3]:2 [inlined] 
in (::##1#f#1)() at ./util.jl:256 

@timeマクロが正常に動作するので、おそらく@allocatedにいくつかのバグがありますか?私はjulia 0.5.0です。

+1

'@ allocated'はその引数を関数内にラップします。したがって、' dot_prod + = v [i] 'はforループのローカル変数です。どのような場合でも、グローバル変数に依存しているので、望む結果を得ることはまずありません。 –

答えて

7

これは--track-allocation=userの制限です。タイプの不安定性はなく、割り当てもありません。

julia> function fuzzy_dot_square(v) 
      dot_prod = zero(eltype(v)) 
      for i in 2:28 
       dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i+28])#/4 # no "top" pixel 
      end 
      for i in 29:(28*27) # compiler should literate 28*27 
       dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28] + v[i+28])#/5 # all pixels 
      end 
      for i in (28*27):(28*28 - 1) 
       dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28])#/4 # no "bottom" pixel 
      end 
      return dot_prod 
     end 
fuzzy_dot_square (generic function with 1 method) 

julia> const xs = [1:28^2;]; 

julia> @allocated fuzzy_dot_square(xs) 
0 

はジュリアdocumentationからも、この一節を参照してください:結果の解釈には

を、いくつかの重要な詳細があります。ユーザー設定では、REPLから直接呼び出される関数の最初の行は、REPLコード自体で発生するイベントのために割り当てを示します。 Juliaのコンパイラの多くはJuliaで書かれており(通常はコンパイルにはメモリ割り当てが必要なため)、JITコンパイルでは割り当て数が増えます。推奨する手順は、分析するすべてのコマンドを実行してコンパイルを強制的に実行し、その後Profile.clear_malloc_data()を呼び出してすべての割り当てカウンタをリセットすることです。最後に、必要なコマンドを実行し、Juliaを終了して.memファイルの生成をトリガーします。

詳細については、を参照してください。

関連する問題