# HG changeset patch
# User Yuhi TOMARI
# Date 1404885196 -32400
# Node ID 3d5fd010131ddefd2569f5dbd3d415046b1a939b
# Parent 105ba499ae4012a320307865a336c36cc62818c2
test
diff -r 105ba499ae40 -r 3d5fd010131d s6/blank.html
--- a/s6/blank.html Tue Jun 24 18:07:06 2014 +0900
+++ b/s6/blank.html Wed Jul 09 14:53:16 2014 +0900
@@ -127,222 +127,42 @@
と特別なチューニングが必要となる。
そこでCeriumを用いてその差を吸収し、自動的なチューニングを可能にする。
-
- しかし、GPUのみで並列計算を行った場合、Taskによっては並列度が出ない場合がある。
- そこでチューニングの一環として、MultiCoreとGPU上での同時実行を可能にする。
-
-
-
-
-
-
進捗
-
- - Scalaで遊んでた
- - mallocのお勉強
- - kernel reading party(小崎さん)
- - 動画
- - 資料
-
-
-
-
mallocってなんだっけ……?
-
- void *malloc(size_t size);
-
-
- - mallocはsizeバイト分のメモリを割り当て、ポインタを返す
- - 返ってくるのはvoidのポインタなので、戻り値を型でキャストする必要がある
- - 中身は初期化されていない
- - 確保した領域はfreeを忘れずに
-
-
- char *str = (char*)malloc(length); // 使う型でキャストする
-
-
-
-
古典的malloc(K&R malloc)
-
-
- - 使用可能なブロックを繋げたリスト構造、free list (freeされているブロックのlist?)
-
- listを使ってメモリを管理
-
- 管理領域(header)分だけ多くallocateして、先頭に管理領域を付加
-
- first fit
-
-
-
- union header {
- struct {
- union header *ptr; // 空きリストの上なら次のブロック
- unsigned size; // このブロックの大きさ
- } s;
- };
-
-
-
-
First Fit
-
- リストを頭から見ていって、最初に見つけたものを使用するというすごいシンプルな方法。
-
-
-
-
-
-
First Fit
-
-
実は、もう一個先にもっと適切なブロックがあった。こんな場合に対応できない…というか、対応しないのがfirst fit。
-
あまりよくない……
-
-
-
-
free
-
- void free(void *ptr);
-
- メモリの開放自体は、使用中のブロックをfree listに追加するだけで良い。
- 引数で受け取ったポインタ部分を開放したら良い……かに思える。
- でもそれだけじゃダメで、開放したい領域と隣接しているブロックが空きブロックなら併合しないといけない。
-
-
-
-
-
-
free
-
-
- listから最初のポインタと、その次のポインタを取得。prev < p < nextを満たすまで走査していく
-
-
free
-
-
あった!!
-
- 開放後に前後のメモリと併合する必要がある場合があるので、prevとp・pとnextが隣接してるか判定する。
-
-
- - (prev+prev-> size) != p なので、隣接していない
- - (p+p-> size) = next なので、隣接している
- ブロックが隣接している場合は併合する。
-
-
-
-
free
-
-
チェックに引っかかったところをマージする。
-
-
-
-
古典的malloc & freeまとめ
-
フラグメンテーションが頻発する。
+
進捗
- - このmallocが主流だった時は「メモリはプログラムの最初に一気に確保するもの」だった
- - メモリが充分に空いている状態で、
- 必要なメモリを一気に確保するならフラグメンテーションは起きにくい
- - 今はJava・C++のようなオブジェクト指向言語、
- Rubyのようなスクリプト言語等、小さいmallocが頻発するものが多い
- - それをfirst fitでやるのはよくない
-
-
-
-
-
-
-
mallocの改良
-
そもそも、一つのfree listで管理することが無理がある
-
サイズ16Byte用のリスト、サイズ24Byte用のリスト……というようにリストを複数作ってやる
-
-
-
-
- |
-
-
- - mallocで要求されたsizeを8で割れば自分が使用するindexとなる
- - 無限にリストを増やすわけにはいかないので、このリストを使うのは512バイト以下の場合のみ
- - 512バイト以上の大きいデータの場合は、特殊な管理を行う
- - 大きいデータと小さいデータを一緒に管理するからフラグメンテーションが進むんだ
- →大きいデータ用の領域がもう一個欲しい →そうだ、mmapを使おう
- |
-
-
-
-
-
-
-
mmapってなんだっけ……?
-
- - ファイル(fdで指定したもの)をメモリにマップする
- - fdで"/dev/zero"を指定することでmmapをメモリ確保APIとして使用
- - このAPIを使ってHuge Blockはmmapで直接kernelから取得する
-
-
- void *alloc_mmap(size_t size) {
- int fd = open("/dev/zero", O_RDONLY);
- void *ret = mmap(addr, length, prot, flags, fd, offset);
- return ret;
- }
-
-
- addr | mapするメモリアドレス。NULLを渡せばkernelがアドレスを選択する。 |
-
-
-
- length | addrから何バイトマッピングするか。 |
-
-
-
- prot | マッピングのメモリ保護の指定。Read Write Exec None等がある。 |
-
-
- flags | マップを要求された時、共有するかコピーを渡すか。 |
-
-
- offset | ファイルの何バイト目からをメモリにマップするか。 |
-
-
-
-
-
-
Huge Block
-
mmapで確保するので、free listからは独立している。
-
-
-
-
- |
-
-
- listを使って管理しているわけではないので、listをたどったりしなくて良い。
-
- ほしかったらmmapして、いらなくなったらmunmapすればよい。
-
- |
-
-
-
- - free list上でフラグメンテーションが起きにくくなった(当たり前)
- - メモリの無駄が少ない
- 大きなメモリは同じサイズでもう一度mallocされる可能性は低いので、
- 使わなくなったらすぐOSに返却するのは正しい
+ - glibcの環境構築
+ - 実はまだgcc...
+ - mallocを(ようやく)読み始めた
-
まとめ
+
glibc 環境構築
+
install
+
+ $ mkdir build;cd build
+ $ ../configure --prefix=/home/hiyoko/glibc-2.19/build/bin
+ $ make --debug -j
+ $ make install
+
compile
+
+ $ g++ -Wall -g -O0 -c malloc_sample.cc -o malloc_sample.o
+ $ g++ -o malloc_sample malloc_sample.o -g -static
+ -I../glibc-2.19/build/bin/include -L../glibc-2.19/build/bin/lib
+
+
+
+
次やること
- - 一見危なそうに見える処理が……
- - HugeBlockをmmapで管理すれば確かに手っ取り早いではあるが、何バイトからをHugeBlockとするかをちゃんと考えないとだめ
-
-
次やること?
-
- - AVLTree
- - 2-2n allocator
- - mallocのソースを読む
+ - malloc読み終わる
+ - 2-2n allocater
+ - 内定者研修に向けて
+ - swiftの勉強...?
-
-
+