またまた、久しぶりです
既に読者はいなくなったこのブログ、最近ピグを始めたのでこうして再開です!
プログラム関係も更新していきたいなぁー
あくまでも覚書程度になっちゃうだろうけど。。。
ピグってどうやって友達作るんだろ?
プログラム関係も更新していきたいなぁー
あくまでも覚書程度になっちゃうだろうけど。。。
ピグってどうやって友達作るんだろ?
ちょっとマニアック その2『mallocのアライメント』
データを動的に扱うためにmallocというものを使う人も
結構多いのではないのでしょうか?
しかしそのmallocの特性上気を使わないといけない場面が有ります。
そもそもmallocでchar型のデータを確保した時って
実際ヒープにはどのくらいの領域を取られるか知っていますか?
正解は8バイトです。
char型は1バイトだろ!!!
っていう人が出てくるかと思いますが、そこがmalllocの特性上に関わるお話
mallocはどのデータ型にも対応するため戻り値がvoid*なのはご存じですよね?
故に32ビットマシンのdoubleにも対応させなくてはいけません。そのため、
取得される領域は8バイトからとなるわけです。
windowsではさほど問題がない(?)のかもしれませんが、重要なのは
メモリを跨いで取得を行わないという事です。←ちょっと言葉が悪いかも
通常メモリとCPUは4バイトのデータバスで転送が行われます。
例をあげて判り易くご説明しましょう。
1.2000番地から4バイト確保
2.2004番地から2バイト確保
3.2006番地から4バイト確保
この時1のデータ転送はデータバス1回、2も1回
しかし3の場合2回の転送が行われる事になります。
データの転送は大変時間がかかるもの、
プログラマならば余計な処理を少しでも減らしたいものですよね??
その問題を解決するためにアライメントというのは大変重要なものだと
言う事がわかると思います。
実際にアライメントしてからのメモリ確保の方法は
何故_alined_mallocを使わないかと言うと、確保した領域が明示的ではないからです。
実際確保する量は内部で勝手にやってしまうため、
100バイトを128バイトでアライメントして確保してと言っても、実際いくら確保されたか
は知ることが出来ないのです。
ではmallocを使ってのサンプル
#include <stdio.h>
#include <iostream>
#include <malloc.h>
int main()
{
static const int ALIGNE_SIZE = 64;
char* str;
str = (char*)malloc((100 + ALIGNE_SIZE -1) / ALIGNE_SIZE * ALIGNE_SIZE);
int size = _msize(str);
std::cout << "malloc時のサイズ:" << size << std::endl;
free(str);
}
出力:
malloc時のサイズ:128
今回は100バイト確保して、64バイトでアライメントをしています。
ちなみにアライメント後に確保された領域のサイズを知るには
_msize(確保したポインタ) これで確保されたサイズを知ることが出来ます。
直接sizeof(str)とかやっても4バイトしか出てきませんよ?
ここで注意!
メモリ確保は最初に言いましたが、8バイト単位で行われます。なので
10バイトとかでアライメントしても無意味です。
こんな感じで終わります
結構多いのではないのでしょうか?
しかしそのmallocの特性上気を使わないといけない場面が有ります。
そもそもmallocでchar型のデータを確保した時って
実際ヒープにはどのくらいの領域を取られるか知っていますか?
正解は8バイトです。
char型は1バイトだろ!!!
っていう人が出てくるかと思いますが、そこがmalllocの特性上に関わるお話
mallocはどのデータ型にも対応するため戻り値がvoid*なのはご存じですよね?
故に32ビットマシンのdoubleにも対応させなくてはいけません。そのため、
取得される領域は8バイトからとなるわけです。
windowsではさほど問題がない(?)のかもしれませんが、重要なのは
メモリを跨いで取得を行わないという事です。←ちょっと言葉が悪いかも
通常メモリとCPUは4バイトのデータバスで転送が行われます。
例をあげて判り易くご説明しましょう。
1.2000番地から4バイト確保
2.2004番地から2バイト確保
3.2006番地から4バイト確保
この時1のデータ転送はデータバス1回、2も1回
しかし3の場合2回の転送が行われる事になります。
データの転送は大変時間がかかるもの、
プログラマならば余計な処理を少しでも減らしたいものですよね??
その問題を解決するためにアライメントというのは大変重要なものだと
言う事がわかると思います。
実際にアライメントしてからのメモリ確保の方法は
_aligned_mallocというものを使えば簡単に出来ます。
しかし今回はそれを使わずmallocだけを使ってアライメントさせます。何故_alined_mallocを使わないかと言うと、確保した領域が明示的ではないからです。
実際確保する量は内部で勝手にやってしまうため、
100バイトを128バイトでアライメントして確保してと言っても、実際いくら確保されたか
は知ることが出来ないのです。
ではmallocを使ってのサンプル
#include <stdio.h>
#include <iostream>
#include <malloc.h>
int main()
{
static const int ALIGNE_SIZE = 64;
char* str;
str = (char*)malloc((100 + ALIGNE_SIZE -1) / ALIGNE_SIZE * ALIGNE_SIZE);
int size = _msize(str);
std::cout << "malloc時のサイズ:" << size << std::endl;
free(str);
}
出力:
malloc時のサイズ:128
今回は100バイト確保して、64バイトでアライメントをしています。
ちなみにアライメント後に確保された領域のサイズを知るには
_msize(確保したポインタ) これで確保されたサイズを知ることが出来ます。
直接sizeof(str)とかやっても4バイトしか出てきませんよ?
ここで注意!
メモリ確保は最初に言いましたが、8バイト単位で行われます。なので
10バイトとかでアライメントしても無意味です。
こんな感じで終わります
基本 その3 『文字配列→数値』
今回紹介するのは
char* の文字配列から
int 数値への変換です。
#include <stdio.h>
#include <iostream>
int main()
{
using namespace std;
char* inBuf = "39";
int size = 0;
int check = strtoul(inBuf, NULL, 10);
if(check == 0x27)
{
cout << "成功" << endl << check << endl;
}
else
{
cout << "失敗" << endl <<check << endl;
}
return 0;
}
出力:
成功
39
strtoulというものを使えば文字配列を簡単に数値に
変える事が出来ます。
戻り値 = strtoul(引数1, 引数2, 引数3)
引数1:変更したい文字配列
引数2:NULLでOK
引数3:基数
戻り値:変更後の数値
さて、引数3に注目してほしいのですが、この命令には基数を決める事が
出来るのです。
つまり2進数や16進数へ変換も可能となります。
今回のサンプルでは10進数の変換にしているので引数3は10にしました。
こんな感じでおっわりー
char* の文字配列から
int 数値への変換です。
#include <stdio.h>
#include <iostream>
int main()
{
using namespace std;
char* inBuf = "39";
int size = 0;
int check = strtoul(inBuf, NULL, 10);
if(check == 0x27)
{
cout << "成功" << endl << check << endl;
}
else
{
cout << "失敗" << endl <<check << endl;
}
return 0;
}
出力:
成功
39
strtoulというものを使えば文字配列を簡単に数値に
変える事が出来ます。
戻り値 = strtoul(引数1, 引数2, 引数3)
引数1:変更したい文字配列
引数2:NULLでOK
引数3:基数
戻り値:変更後の数値
さて、引数3に注目してほしいのですが、この命令には基数を決める事が
出来るのです。
つまり2進数や16進数へ変換も可能となります。
今回のサンプルでは10進数の変換にしているので引数3は10にしました。
こんな感じでおっわりー
ちょっとマニアック その1『物理メモリの使用量を調べる』
さて、ゲーム制作で必要なのかどうかわからない部門として
手始めに物理メモリの使用量の調べ方を書いていきたいと思います。
//現在の物理メモリの状況を表示してみる
#include <stdio.h>
#include <iostream>
#include <windows.h>
int main()
{
using namespace std;
MEMORYSTATUSEX ms = {sizeof(MEMORYSTATUSEX)};
GlobalMemoryStatusEx(&ms);
//空きメモリ
DWORDLONG dwFree = ms.ullAvailPhys;
//使用メモリ
DWORDLONG dwUsed = ms.ullTotalPhys - ms.ullAvailPhys;
//搭載メモリ
DWORDLONG dwSize = ms.ullTotalPhys;
cout << "搭載メモリ:" << dwSize << endl;
cout << "空きメモリ:" << dwFree << endl;
cout << "使用メモリ:" << dwUsed << endl;
return 0;
}
まあこんなかんじです。
特に説明とかはいらないですよね?
とりあえずWin32APIのひとつです。
おっわりー
手始めに物理メモリの使用量の調べ方を書いていきたいと思います。
//現在の物理メモリの状況を表示してみる
#include <stdio.h>
#include <iostream>
#include <windows.h>
int main()
{
using namespace std;
MEMORYSTATUSEX ms = {sizeof(MEMORYSTATUSEX)};
GlobalMemoryStatusEx(&ms);
//空きメモリ
DWORDLONG dwFree = ms.ullAvailPhys;
//使用メモリ
DWORDLONG dwUsed = ms.ullTotalPhys - ms.ullAvailPhys;
//搭載メモリ
DWORDLONG dwSize = ms.ullTotalPhys;
cout << "搭載メモリ:" << dwSize << endl;
cout << "空きメモリ:" << dwFree << endl;
cout << "使用メモリ:" << dwUsed << endl;
return 0;
}
まあこんなかんじです。
特に説明とかはいらないですよね?
とりあえずWin32APIのひとつです。
おっわりー
休みはいいねぇ
休みの日はいいですね、起きる時間とか考えなくていいのが最高です。
と言っても、いつもの時間に目が覚めてしまうのは何故だろうか。。。。
さて、最近始めたプログラムについての記事ですが、
毎週土日辺りには更新したいと考えています。
その他の日は時間が有ればと言う感じで行きたいと思います。
よろしくお願いします。
と言っても、いつもの時間に目が覚めてしまうのは何故だろうか。。。。
さて、最近始めたプログラムについての記事ですが、
毎週土日辺りには更新したいと考えています。
その他の日は時間が有ればと言う感じで行きたいと思います。
よろしくお願いします。
