Recommended
PDF
PDF
Rにおける大規模データ解析(第10回TokyoWebMining)
PPTX
巨大な表を高速に扱うData.table について
PDF
PDF
RのffとbigmemoryとRevoScaleRとを比較してみた
PDF
PPTX
PDF
PDF
統計解析言語Rにおける大規模データ管理のためのboost.interprocessの活用
PDF
PDF
PDF
PDF
PPTX
for関数を使った繰り返し処理によるヒストグラムの一括出力
PDF
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
PDF
Why dont you_create_new_spark_jl
PPTX
PDF
PPTX
Feature Selection with R / in JP
PDF
TensorFlow White Paperを読む
PDF
PDF
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
PDF
PDF
PDF
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
PDF
PDF
PDF
Rが苦手な人にもRを使って頂くために~RcommanderとRook~
PDF
PDF
More Related Content
PDF
PDF
Rにおける大規模データ解析(第10回TokyoWebMining)
PPTX
巨大な表を高速に扱うData.table について
PDF
PDF
RのffとbigmemoryとRevoScaleRとを比較してみた
PDF
PPTX
PDF
What's hot
PDF
統計解析言語Rにおける大規模データ管理のためのboost.interprocessの活用
PDF
PDF
PDF
PDF
PPTX
for関数を使った繰り返し処理によるヒストグラムの一括出力
PDF
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
PDF
Why dont you_create_new_spark_jl
PPTX
PDF
PPTX
Feature Selection with R / in JP
PDF
TensorFlow White Paperを読む
PDF
PDF
PythonでテキストをJSONにした話(PyCon mini sapporo 2015)
PDF
PDF
PDF
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
PDF
PDF
PDF
Rが苦手な人にもRを使って頂くために~RcommanderとRook~
Similar to Rのデータ構造とメモリ管理
PDF
PDF
PDF
PDF
PDF
PPT
PPT
ODP
PDF
PDF
PDF
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
PDF
Precise garbage collection for c
PDF
プログラミングコンテストでのデータ構造 2 ~動的木編~
PDF
PDF
Shibuya.lisp #28: 仮題: R について
PPTX
PDF
PDF
PDF
More from Takeshi Arabiki
PDF
PDF
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
PDF
Introduction to Japanese Morphological Analysis
PDF
PDF
PDF
Introduction to Favmemo for Immature Engineers
PDF
PDF
PDF
PDF
PDF
PDF
PDF
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
PDF
PDF
PDF
PDF
Rのデータ構造とメモリ管理 1. 2. 自己紹介
• Takeshi Arabiki
‣ Web 業界の底辺エンジニア
‣ Twitter & はてな: @a_bicky & id:a_bicky
• 興味など
機械学習、自然言語処理、R
• ブログ
あらびき日記 http://d.hatena.ne.jp/a_bicky/
3. R関係の主な発表
Tokyo.R #16 Tsukuba.R #9 Rユーザ会 2011
http://www.slideshare.net/abicky/r-9034336 http://www.slideshare.net/abicky/r-10128090 http://www.slideshare.net/abicky/rtwitter
4. 5. 6. 2つのデータ構造
SEXPREC
たぶん Symbolic EXPression RECord (S-EXPression RECord) の略
*SEXP = SEXPREC
VECTOR_SEXPREC 以外のノード(オブジェクト)
VECTOR_SEXPREC
SEXPREC の Vector 版(メモリを少し節約)
*VECSEXP = VECTOR_SEXPREC
データ部分は直後のアドレスに格納
raw, logical, integer, numeric, complex, character, list, expression 等
7. SEXPREC
// cf. src/include/Rinternals.h
typedef struct SEXPREC {
struct sxpinfo_struct sxpinfo; // 詳細は後述
struct SEXPREC *attrib; // 属性情報
struct SEXPREC *gengc_next_node; // GC で使用
struct SEXPREC *gengc_prev_node; // GC で使用
// データ部分
union {
struct primsxp_struct primsxp;
struct symsxp_struct symsxp;
struct listsxp_struct listsxp;
struct envsxp_struct envsxp;
struct closxp_struct closxp;
struct promsxp_struct promsxp;
} u;
} SEXPREC, *SEXP;
8. VECTOR_SEXPREC
// cf. src/include/Rinternals.h
typedef struct VECTOR_SEXPREC {
struct sxpinfo_struct sxpinfo; // 詳細は後述
struct SEXPREC *attrib; // 属性情報
struct SEXPREC *gengc_next_node; // GC で使用
struct SEXPREC *gengc_prev_node; // GC で使用
struct vecsxp_struct vecsxp; // length, truelength
} VECTOR_SEXPREC, *VECSEXP;
// データ部分のアライメントをするための変数?
typedef union {
VECTOR_SEXPREC s;
double align; } SEXPREC_ALIGN;
// データ部分の先頭アドレスの定義
#define DATAPTR(x) (((SEXPREC_ALIGN *) (x)) + 1)
9. VECTOR_SEXPREC
VECTOR_SEXPREC のイメージ
VECTOR_SEXPREC
ノード
sxpinfo attrib gengc_next_node
gengc_prev_node vecsxp_struct
データ部分 sizeof(VECREC) * length
10. sxpinfo_struct
// cf. src/include/Rinternals.h
struct sxpinfo_struct {
SEXPTYPE type : 5; // ノードのタイプ
unsigned int obj : 1;
unsigned int named : 2; // コピーの際の挙動を制御
unsigned int gp : 16;
unsigned int mark : 1; // Mark-and-Sweap の mark
unsigned int debug : 1;
unsigned int trace : 1; // tracemem 等で使用
unsigned int spare : 1; // もう使われていないらしい
unsigned int gcgen : 1; // GC の世代情報
unsigned int gccls : 3; // サイズに応じたクラス番号
};
11. 12. 基礎知識
• メモリ管理の上でノードは3種類に分かれる
‣ non-vector (gccls = 0)
‣ small vector(gccls = 1, 2, 3, 4, 5, 6)
‣ large vector (gccls = 7)
• GC は世代別 GC
‣ old 世代は gcgen = 0, 1 の2つ存在
‣ old 世代からより若い世代への参照は参照が発生する度
にリストに追加する形で管理(デフォルトオプション)
13. R の世代別 GC
各世代は双方向リストとなっている
→ 挿入・削除を定数時間で行える
R_GenHeap[gccls].New R_GenHeap[gccls].Old[gen]
= &R_GenHeap[gccls].NewPeg = &R_GenHeap[gccls].OldPeg[gen]
gengc_prev_node
gengc_next_node
node3 node1
node2 node1
node2
gen th
New generation Old generation
14. R の世代別 GC の手順
1. old 世代のうち何番目の世代までを GC 対象とするか決定
2. GC 対象の old 世代から参照されているノードを参照元世代に移す
3. GC 対象の old 世代の世代 (gcgen) をインクリメントして unmark
した上で new 世代に移す
4. GC 対象外の old 世代から参照されているノードを mark し old 世
代に移す
5. root からたどって参照のあるノードを mark し old 世代に移す
6. large vector の new 世代に存在するノードを解放
7. 場合によっては non-vector, small vector のうち unmarked な
ノードを解放
cf. RunGenCollect (src/main/memory.c)
15. gc 関数の結果の意味
> gc() # 全世代を対象とした GC (full GC)
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 180515 9.7 407500 21.8 350000 18.7
Vcells 287939 2.2 905753 7.0 877008 6.7
used Mb
使用中のノードの数。 sizeof(SEXPREC) x
non-vector, small ノードの数 / 1024 /
Ncells
vector, large vecotor 全 1024
てを含む。
全 vector ノードのデータ ← を個数ではなく Mb で
部分(ヘッダ部分を除 表した値。
Vcells
く)が VECREC 何個分の つまり sizeof(VECREC)
サイズに相当するか x 個数 / 1024 / 1024
16. メモリ確保の仕組み
• small vector
1. データ部分のサイズが VECREC 何個分相当かを算出
2. 1 の結果が1以下であれば gccls = 1、2以下は2、4以下は3、6
以下は4、8以下は5、16以下は6という具合に gccls をセット
3. 対応する gccls の使用されていないノードを割り当てる
4. 使用されていないノードが存在しない場合は一定量のノードを新
しく生成 (GetNewPage)
• non-vector
‣ ↑の手順のうち gccls を 0 とする
17. メモリ確保の仕組み
• large vector
1. データ部分のサイズが VECREC 何個分相当かを算出
2. 1 の結果が16より大きければ gccls を 7 にセット
3. 必要なサイズをその都度 malloc で確保
いずれの場合もメモリが足りない場合は GC を実行したり
ヒープサイズを調整する
18. tracemem の仕組み
// cf. src/main/duplicate.c
SEXP duplicate(SEXP s){
SEXP t;
duplicate_counter++;
t = duplicate1(s);
// (s)->sxpinfo.trace フラグが立っていればレポートを出力
if (RTRACE(s) && !(TYPEOF(s) == CLOSXP ||
TYPEOF(s) == BUILTINSXP ||
TYPEOF(s) == SPECIALSXP ||
TYPEOF(s) == PROMSXP ||
TYPEOF(s) == ENVSXP)){
memtrace_report(s,t);
// コピーしたノードにもフラグを立てる
SET_RTRACE(t,1);
}
return t;
}
19. tracemem の挙動
duplicate が呼ばれないコピーはトレースできない
> tracemem(a <- 1:5)
[1] "<0x103011a48>"
> b <- a
> b[1] <- 1 # そのまま代入した場合はトレースされる
tracemem[0x103011a48 -> 0x101b41760]:
tracemem[0x101b41760 -> 0x103063188]:
> c <- a[1:5]
> c[1] <- 1 # インデックスを指定した場合はトレースされない
> tracemem(a <- list(a = 1:5))
[1] "<0x1064c0958>"
> b <- a
> a$a <- 1 # そのまま代入した場合はトレースされる
tracemem[0x1064c0958 -> 0x1067e9598]:
> c <- a$a
> c[1] <- 1 # 一部の要素の代入はトレースされない
20. 21. 参考文献
• R Internals - 1.1 SEXPs
http://cran.r-project.org/doc/manuals/R-ints.html#SEXPs
• RObjectModel - r-optimization-engine - Optimizing the
performance of R - Google Project Hosting
http://code.google.com/p/r-optimization-engine/wiki/
RObjectModel
• R 2.15.2 のソースコード
主に src/include/Rinternals.h, src/main/include/Defn.h,
src/main/memory.c
22. 変更履歴
• 2012/12/15
世代別 GC の旧世代の世代数が2なのに3になっていたのを訂正