0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

D言語の配列領域の再確保を調べてみた

Posted at

犯行動機、かく語れり


 D言語の配列が付け足し等によって、どのように延長されるのか?を試してみました。
 配列を接続した際、メモリがどれだけ慌ただしく動くのか?を知っておきたかったんです。

検証


 内容は至って簡単。

  1. byte型動的配列(buffer)に1要素(=1バイト)ずつ足していく。
  2. 配列の先頭アドレス(buffer.ptr)からメモリブロック情報(BlkAttr)を、GC.query関数で取り出す。
  3. 確保先頭アドレスとその長さが変わったら、標準出力。
  4. 出力結果をじっくりたっぷりねぶりあげるように観察。

 テストコードは以下のとおり。

testcode.d
import
    core.memory ,
    std.stdio ;

void main()
{
    byte[] buffer;
    void*  base = GC.query(buffer.ptr).base;
    size_t size = GC.query(buffer.ptr).size;
    
    writefln( "length=% 8d, ptr=xxxxxxxx -> %08X, length=% 8d",
              buffer.length,
              base,
              size
            );
    
    foreach( i ; 0 .. 1024*1024 ){
        buffer ~= 0;
        
        auto bi = GC.query(buffer.ptr);
        
        if( base != bi.base || size != bi.size ){
            writefln( "length=% 8d, ptr=%08X -> %08X, length=% 8d(% +8d)",
                      buffer.length,
                      base,
                      bi.base,
                      bi.size,
                      bi.size - size
                    );
            base = bi.base;
            size = bi.size;
        }
    }
}

結果


output:
length= 0, ptr=xxxxxxxx -> null, length= 0
length= 1, ptr=null -> 009D1FE0, length= 16( +16)
length= 16, ptr=009D1FE0 -> 009D2FE0, length= 32( +16)
length= 32, ptr=009D2FE0 -> 009D3FC0, length= 64( +32)
length= 64, ptr=009D3FC0 -> 009D0F00, length= 128( +64)
length= 128, ptr=009D0F00 -> 009D4F00, length= 256( +128)
length= 256, ptr=009D4F00 -> 009D5E00, length= 512( +256)
length= 511, ptr=009D5E00 -> 009D6C00, length= 1024( +512)
length= 1023, ptr=009D6C00 -> 009D7800, length= 2048( +1024)
length= 2047, ptr=009D7800 -> 00BD0000, length= 4096( +2048)
length= 4080, ptr=00BD0000 -> 00BD0000, length= 8192( +4096)
length= 8176, ptr=00BD0000 -> 00BD0000, length= 16384( +8192)
length= 16368, ptr=00BD0000 -> 00BD0000, length= 28672( +12288)
length= 28656, ptr=00BD0000 -> 00BD0000, length= 49152( +20480)
length= 49136, ptr=00BD0000 -> 00BD0000, length= 65536( +16384)
length= 65520, ptr=00BD0000 -> 00BD0000, length= 69632( +4096)
length= 69616, ptr=00BD0000 -> 00BD0000, length= 110592( +40960)
length= 110576, ptr=00BD0000 -> 00BD0000, length= 131072( +20480)
length= 131056, ptr=00BD0000 -> 00BD0000, length= 135168( +4096)
length= 135152, ptr=00BD0000 -> 00BD0000, length= 212992( +77824)
length= 212976, ptr=00BD0000 -> 00BD0000, length= 262144( +49152)
length= 262128, ptr=00BD0000 -> 00BD0000, length= 266240( +4096)
length= 266224, ptr=00BD0000 -> 00BD0000, length= 405504( +139264)
length= 405488, ptr=00BD0000 -> 00BD0000, length= 458752( +53248)
length= 458736, ptr=00BD0000 -> 00BD0000, length= 462848( +4096)
length= 462832, ptr=00BD0000 -> 00BD0000, length= 704512( +241664)
length= 704496, ptr=00BD0000 -> 00BD0000, length= 720896( +16384)
length= 720880, ptr=00BD0000 -> 00CD0000, length= 1081344( +360448)

推察(ソースを見ずに)


  1. アロケーション領域をその場から伸張できる場合、伸ばす(自動で伸ばす長さに法則性が見出だせず)。
  2. 伸張できない場合、再確保+配列コピーを実施。

まだ調べたいこと


 マルチスレッド環境下でのアロケーション性能とかも気になる所。とはいえ、実行速度にセンシティブな運用(ゲームユースとか)だと、アロケーション系命令の実行機会最小化を目指す工夫が必要かも。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?