OS win7 64bit
コンパイラ vs2010,Releaseビルド(exeをダブルクリックで起動).
バイト境界 4
<したいこと・問題点>
std::setを使用した際のメモリ使用量を求めようとしております.
しかし,vs2010のstd::setのメモリ使用量の計算値と
タスクマネージャー(又はProcessExplore)のプライベートワーキングメモリが整合しません.
OSが気を効かせてくれたにしては,少し多すぎるような気がしております.
<実験方法>
setに1000000個の構造体を入れて確認してみました.
set制御用のメモリが12bytes,挿入した構造体はPadding含め8bytes(int,char)と12bytes(char int char)で,
1要素のTotalはそれぞれ,20bytes/24bytesです.
//アロケータで確認済.
本来ならば,
1000000 * 20 = 20000000 = 19531.25 kbytes
1000000 * 24 = 24000000 = 27343.75 kbytes
となるはずです.
しかし,Windowsタスクマネージャー(ProcessExploreでも同様)で確認したところ,
それぞれ
20bytes -> 31372 K
24bytes -> 39220 K
となり,明らかに違いが生まれました.
この違いは一体どこからくるものなのでしょうか?
<コード>
//Setの要素のはず.xtree.hの中にあったものを少し変形.
//struct Node{
//Node* _Left; //左へのポインタ (4byte)
//Node* _Parent; //親へのポインタ (4byte)
//Node* _Right; //右へのポインタ (4byte)
//value_type _Myval;//setに格納される値 (xbyte)
//char _Color; //赤黒 (1byte) //
//char _Isnil; //headの時true (1byte) //(2:char 2:padding)
//};
// total : 4+4+4+ x +4 = 12+x (bytes)
using namespace std;
//メモリ確保量確認用アロケータ
template<class T>
class myallocator : public std::allocator<T> {
public:
myallocator() { }
myallocator(const myallocator& x) { }
template<class U>
myallocator(const myallocator<U>& x) { }
pointer allocate(size_type n, const_pointer hint = 0) {
std::cout << "allocate " << n * sizeof(T) << "bytes" << std::endl;
return (pointer) std::malloc(n * sizeof(T));
}
void deallocate(pointer ptr, size_type n) {
std::cout << "free pointer " << (void*) ptr << std::endl;
std::free(ptr);
}
template<class U>
struct rebind { typedef myallocator<U> other; };
};
struct test1{
char a; // 4 (1:char 3:padding)
int b; // 4
}; //8bytes -> total 12+8 = 20bytes
struct test2{
char a; // 4( 1:char 3:padding)
int b; //4
char c;// 4( 1:char 3:padding)
}; //12bytes -> total 12+12 = 24bytes
struct Test1LessThan : less<struct test1> {
bool operator()( struct test1 a, struct test1 b ) { return a.b > b.b; }
};
struct Test2LessThan : less<struct test2>{
bool operator()( struct test2 a, struct test2 b ) { return a.b > b.b; }
};
void test1(){
set< struct test1,Test1LessThan, myallocator<struct test1> > s;
for(int i=0;i<1000000;i++){
test1 t;
t.b=i;
s.insert(t);
}
}
void test2(){
set< struct test2,Test2LessThan, myallocator<struct test2> > s;
for(int i=0;i<1000000;i++){
test2 t;
t.b=i;
s.insert(t);
}
}
//バイト境界確認
template <typename T>
class alignof{
struct helpler{
char a_;
T b_;
};
public:
static const size_t value = offsetof( helper, b_);
};
int main(){
int a;
cout << alignof<test1>::value << endl; //バイト境界は4
cin >> a;//とめる
test1(); // 計算通りなら,1000000*20bytes = 19.07MB
cin >> a;//とめる
test2(); // 計算通りなら,1000000*28bytes = 26.7MB
return 0;
}