1read 100read
2013年17ゲ製作技術8: C/C++ゲーム製作総合スレッド Part4 (175)
TOP カテ一覧 スレ一覧 2ch元 削除依頼 ▼
■吉里吉里/KAG/TJS雑談質問スレ■その27 (469)
****創価ゲームを作ろうよ***** (155)
C# C# C♯ でゲームを作ろう Part2 (411)
2ちゃんSRPG制作スレッド (129)
■ゲームは終わっているのか!?■ (345)
ひきこもり達でギャルゲーを作るスレ (162)
C/C++ゲーム製作総合スレッド Part4
- 1 :2013/08/12 〜 最終レス :2013/09/24
- ゲーム製作におけるC/C++全般に関するスレです。
元スレ
DXライブラリ 総合スレッド その12
http://toro.2ch.net/test/read.cgi/gamedev/1330000532/
前スレ
C/C++ゲーム製作総合スレッド Part1
http://toro.2ch.net/test/read.cgi/gamedev/1337516528/
C/C++ゲーム製作総合スレッド Part2
http://toro.2ch.net/test/read.cgi/gamedev/1351015269/
C/C++ゲーム製作総合スレッド Part3
http://toro.2ch.net/test/read.cgi/gamedev/1357899040/
- 2 :
- >>1乙
ゲームの解像度を640×480から1280×720に変更したら、画面が広い広い。
- 3 :
- そして縦長画面のゲームを作るんですね
- 4 :
- つ [ピボット機能付きLCD]
- 5 :
- std::vectorのポインタってどうやってかっこよくランダムアクセスできますか?
(*vectorArrayp).Size() //ださい
(*vectorArrayp)[i]->GetHoge //ださい
↑こんなんでなく↓こんな感じで2行目の方法がよくわから
vectorArrayp->Size() //かっこいい
vectorArrayp->[i]//???
- 6 :
- >>5
上と下、意味変わってると思うんだが
- 7 :
- stl とかあまり使ったことないけど、こんな感じで行けるんじゃなかったか
vectorArrayp->at(i)->GetHoge
あまりかっこよくはないが
- 8 :
- GetHogeに括弧がないのが気になる
- 9 :
- コンテナをあまりポインタで扱ったことないけど、
defineかtypedefで何とかならんか?
- 10 :
- templateでいいじゃんよ
- 11 :
- pv[0][i]->m()
ちょっときもちわるいな
- 12 :
- クラスのポインタに入れて渡すか参照渡しを使うことが多いので配列をポインタにして使うってあんまり無い
- 13 :
- >>5
標準ライブラリを使うのは標準化を指向してるからだろ?
なら美醜の感覚(主観)を抑えた方がいいんじゃないかな
初心者の内から美意識に拘るのはハマり道の入り口だし
- 14 :
- >>12
接触した相手を、接触判定クラスから通知する感じでvectorに突っ込んでるんですけどダメですかね・・・
- 15 :
- 俺も複数のオブジェクトを保持するクラス作っちゃうね。
インスタンスの管理もしたいし。
だから、vectorを直接渡すってのは殆ど無い。
- 16 :
- >>14
クエリー結果のリスト(←線形リストではなく広義のリストね)を返す的な感じ?
非公開の(内部的な)やり取りならクエリー結果のリストを生のコンテナ(vector)で
ポンと渡すってのはアリじゃね?お互い身内同士だから結合度高くてオーケー。
お互いよく知らんもの同士、実装(リストがどんなコンテナに入れられてるか)を
知らない相手なら結合度を低めだから、vectorを仲介クラスにコンポジションするかな。
多分それが>>15の話かな
- 17 :
- 難しくてよくわかんないです
具体的に言うと
キャラクタクラスが個々で持ってる、接触した相手のvector配列があってそれに通知と称して相手を渡してます。
で、キャラクターは更新時に通知を見て自分が何にあたったかをその場で判断してリアクションを取ります。
class CCharacter{
vector<CCharacter*> PendingCollisionList;
}
class CollisionObjectList{
vector<CCharacter*> List;
void Judge(){
for(size_t i=0;i<List.size();i++){
for(size_t t=i;t<List.size();t++){
if(接触判定){
List[i]->PendingCollisionList.push_back(List[t]);
List[t]->PendingCollisionList.push_back(List[i]);
}
}
}
}
}
}
- 18 :
- インデントがああ
- 19 :
- vectorをポインタで使うって話はどこいったの
- 20 :
- あ、こうでした
void Judge(vector<CCharacter*>* PendingCollisionList){
for(size_t i=0;i<List.size();i++){
if(接触判定){
(*PendingCollisionList).push_back(List[t]);
}
}
}
- 21 :
- >>20
なぜ参照渡ししないのか??
変数・巻数の命名もなんかちょっとねえ・・・Judge?
それに、クラスのメンバ変数だけかと思ったらローカル変数まで先頭大文字だな
- 22 :
- 命名規則は人それぞれ
そこにケチつけるのは間違ってる
- 23 :
- リアルタイム処理でpush_backするのは頂けないなぁ。
push_back呼び出し毎でないにしろ、結構な頻度でメモリ確保する事になるし。
自分なら、最初からキャラクタ最大数分確保しておく。
で、本題だけど、vector<CCharacter*>を直接渡すんじゃなくて
vectorの入ったCCharacterListみたいなクラスを作ってそれをポインタなり参照なりで渡す。
それが>>12-15あたりで出てる話でないの?
- 24 :
- 毎度毎度出てくる話だけど、数百程度をpush_backしようが、
システム全体のベンチマークを取ると誤差程度も違いが出ない。
何となく時間がかかりそうだと、測定もせずに言い出す馬鹿が毎度涌くのは勘弁して欲しい。
- 25 :
- 何をもってリアルタイム処理と言っているんだろう
- 26 :
- マジか?と思ってテストコード書いた。デバッグモードでの結果だけど
vector<int>でpush_back()100回後、clear()。このセットを10,000回 -> 432ms
malloc()で4byte確保、直後free()。このセットを1,000,000回 -> 1785ms
開発中はデバッグモードでもコード走らせるし、
mallocの1/4程度じゃちょっと無視する気持ちになれないなぁ。
全てのキャラクター同士の衝突判定をすれば、階乗的に処理数が増えるし。
もちろんキャラクター数にもよるけどね。
やっぱり安全策をとって予め確保しておくことにするよ。
- 27 :
- ほら、局地的にしか測定しない馬鹿だろう。
システム全体では測定不能な誤差に埋もれるレベルにしかならないという話をしているのに、
全然違うことをしている上にDebugで測定。
Releaseではご満足な結果が出なかったから仕方なかったんだろうけどさ。
メモリ確保が遅いとか吹聴するのは、毎度毎度こういうどうしようも無いクズばっかりだよ。
- 28 :
- 傍から見てる分には27の方がバカに見えるけどな。
1)自分では実際に計測せずに人のやり方にケチつけるだけ。
2)誤差の範疇かどうかは当人が決める事。
- 29 :
- キャシャーンがやらねば、誰がやる!
- 30 :
- 他の人から突っ込みがあるかと思って待ってたんだけど、
出ないみたいだからもう一つ突っ込んでおくよ。
std::vectorでclear呼んでもメモリは解放されない。
つまり別のところで時間を食ってるだけ。
あまりにお粗末すぎないか?
- 31 :
- あっ・・・
- 32 :
- >std::vectorでclear呼んでもメモリは解放されない。
らしいので計測。懐疑主義者がいるようなのでリリースモードでも計測。
新しく生成されたvector<int>でpush_back()100回。
このセットを10,000回 -> 1209ms(デバッグ) , 462ms(リリース)
因みに予め確保したvectorに0を1,000,000回代入 -> 94ms(デバッグ), 2ms(リリース)
うーん、都度のメモリ確保はやっぱり重いよ。
ID:NCVPitu3はこの質問スレで>>14をスルーして私のコーディングにしか興味が無いようだけど。
2chらしい煽り文句を着飾って私に何を言いたいの?
- 33 :
- 質問スレじゃないな。失礼。
- 34 :
- #include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
timeBeginPeriod(1);
DWORD t = timeGetTime();
int i,j;
for(j=0;j<10000;j++)
{
for(i=0;i<100;i++)
{
std::vector<INT> v;
//v.reserve(100);
v.push_back(0);
}
}
printf("%d\n",timeGetTime()-t);
return 0;
}
試せば分かるが、そんな差は出ない。
clearの動作すら分かっていなかったし、書いているソースがおかしいだろう。
- 35 :
- >>34
それ再確保動作行われないがただの typoか?
std::vector<INT> v; はループの外に置かないと、ただ毎回初期エクステントサイズで生成されてスコープアウトで解放するだけだよな。意味違う
- 36 :
- もしも本当に勘違いしてるとして、一応補足しておくと、
vectorの確保領域は連続したメモリ空間に配置される事が保証されているので、
それを守るためには初期エクステントで生成(mallocのような動作)とfreeの動作だけでなく、増加させたサイズ分の確保とコピー(reallocのような動作)を再現しないと
多分話ズレるよ
- 37 :
- #include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
timeBeginPeriod(1);
DWORD t = timeGetTime();
int i,j;
for(j=0;j<100000;j++)
{
std::vector<INT> v;
//v.reserve(100);
for(i=0;i<100;i++)
{
v.push_back(0);
}
}
printf("%d\n",timeGetTime()-t);
return 0;
}
たしかに間違い。
こっちで試してくれ。
- 38 :
- 何をどうやっても>>32のような462/2*1000000/10000=23100倍なんて差は出ない。
- 39 :
- そうやってシステムに組み込まれたら、ほとんど分からなくなるような部分を、
ループで過剰に回して、さも全体にかかる負荷が大きいように吹聴するのが糞なんだよ。
- 40 :
- そんなに気にするのなら毎回clear()したvectorを使うと良い
数が足りていりゃ何もしないし足りなければ追加で確保してくれる
最大オブジェクト数を設定してそのサイズに合わせるとかするよりはマシ
そんなに使うかわからないのに初めからそんなに確保する事はない
そのコード何を比べているんだ?push_backした時と一気に確保した時の違い?
最初に確保しておけば、毎回確保する必要がないって話ではなかったのか?話変わってね?
stlのvectorってpush_back毎ではなくてある程度まとめて確保しているらしいが
1回数百バイト程度では毎回確保してもまあ誤差程度な気はする
- 41 :
- ループ内で何もしないコードの実行時間とメモリ確保を繰り返すコードの実行時間を比べるのは意味不明
- 42 :
- 最初から確保しようが、std::vectorで動的に確保しようが、
数百程度のキャラクターのデータなら、
システム全体では誤差で測定不能になる程度の影響しか与えない。
首尾一貫して何度も言っているんだが。
大量にループを回してもせいぜい数倍程度しか差が出ない内容で、
ソースも出さずに23100倍の結果だけ書いていく頭の悪さは何なんだ?
- 43 :
- 結論的に、intのpush_backでは代入とほぼ同じくらいの軽い処理ってこったろ。
いつから、push_backとメモリ確保の話がごっちゃになってんだ?
ついでに、>>37 のようなソースでは毎回同じアドレスからstd::vector<INT> vを割り当ててると思うので、
mallocのキャッシュが利いてるはず。これはあまりよろしくないメモリ確保の時間測定に見える。
- 44 :
- ちなみにvectorって毎回のpush_backで毎回再確保&コピーはされないけど一定量越える度にコストがO(n^2)くらいの指数増加してくので、
予め上限がわかってたらreserve()するのが常套手段だよな
- 45 :
- mallocって同じアドレスだと速いの?
- 46 :
- >>43
#include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
timeBeginPeriod(1);
DWORD t = timeGetTime();
int i,j;
for(j=0;j<100000;j++)
{
std::vector<void*> v;
//v.reserve(100);
for(i=0;i<100;i++)
{
v.push_back(malloc(rand()%100));
}
for(i=0;i<100;i++)
{
free(v[i]);
}
}
printf("%d\n",timeGetTime()-t);
return 0;
}
>mallocのキャッシュが利いてるはず。これはあまりよろしくないメモリ確保の時間測定に見える。
文句があるなら、自分でソースを出せよ。
で、具体的にmallocのキャッシュとやらを測定するソースを出してみろ。
当然、測定した上での発言なんだろ?
- 47 :
- >>44
256で上限に達したら65536のコスト?
そんな馬鹿な実装のstlがどこにあるのか、後学のために教えてくれ。
- 48 :
- ゲーム1フレーム内での数百程度のpush_backなんか気にすんなってのはID:zpg6JFDeと同意見だな
ただ、プロのゲームプログラマになるのなら必ずしもSDKに付いてくるstd::vectorの拡張処理が効率的になってるとは限らないということを覚えておいてほしい
reserveなんかいらねぇぜって思ってたらpush_backが毎度1個分ずつ確保する実装だったでござるっていうのもあったから
- 49 :
- あほばっかw
- 50 :
- for(j=0;j<100000;j++)
{
std::vector<int> v;
//v.reserve(100);
for(i=0;i<100;i++) { v.push_back(0); }
}
printf("%d\n",timeGetTime()-t);
t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
//v.reserve(100);
for(i=0;i<100;i++) {
v.push_back(malloc(100));
free(v[i]);
}
}
printf("%d\n",timeGetTime()-t);
t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
//v.reserve(100);
for(i=0;i<100;i++){ v.push_back(malloc(100)); }
for(i=0;i<100;i++){ free(v[i]); }
}
printf("%d\n",timeGetTime()-t);
- 51 :
- reserve無し
171
882
1123
reserve有り
36
746
984
約1.3倍速い
- 52 :
- いったいmallocのキャッシュって何のことだ
vector::reserveのことなのかmallocに魔法があるとでも
- 53 :
- >>51
その結果見ると140ms程度がreserveで改善されてるって感じじゃないの
1回あたり140nsのオーバーヘッド
1フレームで1000回以上呼び出されるようなら無視できないレベルだと思うけど
push_backの使いどころってそんなにあるかね?
- 54 :
- >>48
>reserveなんかいらねぇぜって思ってたらpush_backが毎度1個分ずつ確保する実装だったでござるっていうのもあったから
具体的にどのstl?
あるかもしれないではなく、「あった」と言っている以上、当然知ってるよね。
>>50
全然mallocキャッシュとやらの検証は出来ていないが、頭は大丈夫か?
そもそも人のソースじゃ無くて自分のソースを出せよ。
当然、以前に自分が検証したソースがあるんだろう?
>>53
140ms/(100000*100)=14ns
- 55 :
- >>54
1000万回か100万回と勘違いしてた
- 56 :
- >>51だと
2つ目のmallocしてすぐにfreeしている版が少し速いから使い回しされている感がある
Windowsはfreeされたメモリ領域を覚えているなど管理がわりと賢い
http://marupeke296.com/cgi-bin/cbbs/cbbs.cgi?mode=al2&namber=2568&rev=&no=0&P=R&KLOG=3#5
reallocは連続した領域があればメモリコピー無しで終る(らしい
mallocもreallocも、実装や実行時の状況次第で所要時間が変わるからコストを評価しづらい
- 57 :
- 夏ダナー
- 58 :
- >>56
>mallocもreallocも、実装や実行時の状況次第で所要時間が変わるからコストを評価しづらい
だからシステム全体では誤差に埋もれる程度の差しかないと何度も言っているだろう。
実際にはやらないようなあり得ない数を回して、ようやく測定できるレベルなんだから。
- 59 :
- そうね。
- 60 :
- >>54
PS3のstlですな
- 61 :
- >>60
ps3といってもcellのコンパイラや流出したSDKなど色々あるんだが、
具体的にどのSDKのどのバージョン?
- 62 :
- 科学的な話のはずなのに何か宗教論争じみて感じるこの感覚・・・不思議!
- 63 :
- push_back分のメモリが確保できない場合、新たな領域確保後、要素数N-1分コピーされるわけで、
このコストを無視出来るかどうかは、要素数にもよる
push_backで確保できない場合、結局内部的には一定量(実装依存)reserve&コピーされていく。
(例えばVC2012でreserve数の変化は1 2 3 4 6 9 13 19 28 42 63 94 141という感じ)
したがって要素数があらかじめ予想できるならば、最初からreserveしておけば無駄がない。
あらかじめ要素数が予想できない上に、リソースが潤沢なハードなら、reserveせずにvectorの実装に任せてもいいかもね。
- 64 :
- おひおひwwwwww
またゎいトンのχ
>>42
>>数百程度のキャラクターのデータなら、
>>数百程度のキャラクターのデータなら、
>>数百程度のキャラクターのデータなら、
そんなに威張れる「システム全体」なんか?wwww
もどきの体裁を取り繕う程度の仕様なんじゃね。
短小首尾一貫カッコイイッスネwwwww
- 65 :
- >>63
>このコストを無視出来るかどうかは、要素数にもよる
こういう発言の何が問題なのかというと、無視できなくなる具体的な数や状況を全く明示せずにソースの提示もしないこと。
そういった前提条件が無くなると議論のしようも無く、正しく宗教論争を起こすきっかけにしかならない。
- 66 :
- ボードゲームのAIのアルゴリズムのminmax法って、
奇数手先(相手の手)を評価するの?
それとも偶数手先(自分の手)を評価するの?
- 67 :
- 勝ちから逆算する学習アルゴリズムでない限り
そのへん全ては自分で決めるもんだと思うよ
- 68 :
- >>65
それを言うなら貴方の言う「システム全体」も漠然としすぎてるんじゃない?
「フルマラソンするには数リットルの給水が必要だ」と言ってる相手に
「通常生活おくるだけならそんなに給水は必要ない」って言ってるように聞こえるんだけど。
- 69 :
- >>54
どこが検証できていないか具体例でよろしく。
第一自分のソースとか関係ない。
単純な繰り返しの場合、速く確保できてるのを示すだけだから。
reserveは行きがけの駄賃。俺なら最初に確保しとくね。
- 70 :
- >>68
道路に微妙に落ちている砂を事前に払っておかないと、
マラソンのタイムに影響するという方が正しい。
そもそも毎フレーム再確保するという前提自体、
そうしないと完全に測定不能なほど小さい値だからやっているだけで、
普通のシステムなら初期化やシーン切り替え時に確保作業は終わっている。
シーンの切り替えに発生する数マイクロセカンドをどうやって測定するんだ?
そうなると何をどうやっても差が生まれないんだが、
無いものを無いと証明するのは悪魔の証明で不可能だ。
だったら差が生まれる前提条件を明示しないと議論しようが無い。
なぜあると言っている奴が、条件すら書けないんだ?
>>69
mallocキャッシュとやらが効いている場合と効いていない場合で、
結局どれだけ差があるのか数値化できていない。
結果から引き算で求めるというのなら簡単に論破する準備があるから、
具体的な数字をだしてみな。
- 71 :
- なーにいきり立ってんだ?
実装によって異なるみたいだけどSTL自体のソース読めば済む話じゃないのん
せめてやるならMSVCだとかWindowsだとか限定しないとねぇ…
- 72 :
- >>70
>>51
- 73 :
- >>71
限定するとあるある派の逃げ道がなくなるからあえて塞がなかったんだけど。
旧世代のPDAとかリソースが貧弱で、これだけ影響するぞっていうのを期待していたんで。
毎フレームメモリを確保し直すとかいうプログラムの目的は想像がつかないから実例を挙げる難易度は高いけど。
Windowsに限定したらそういうのが無理になるだろう。
>>72
やっぱり答えないと思ったよ。
mallocキャッシュとやらの有無による違いは具体的に何ms?
ノイズが多すぎて検証しようが無いよね。
そもそもmallocキャッシュって何?
ハード側のキャッシュメモリが働くのを期待しているということ?
それともmalloc自体に何らかのキャッシュ機構があるってこと?
- 74 :
- >>73
単位はmsなんだから3番目から2番目引いたら出るだろ。
1000万回で(この場合はreserve関係ないけど)有り241msと無し238ms
そう。malloc自体になにかある。同じアドレスは速い。
- 75 :
- >>74
やっちゃったね、引き算。
ループの数が違うから、最適化やジャンプに引っ張られて検証なんて出来ないよ。
- 76 :
- ちなみにこれがmallocキャッシュという謎の機構では無く、
空いている領域をきっちり調べていることを示すサンプル。
事前にデータが確保されている数が多いほど、探索に時間がかかる。
これも数を極端にしないと、検証できないレベルだけどね。
int main()
{
timeBeginPeriod(1);
int i,j;
DWORD t = timeGetTime();
while(timeGetTime()-t > 2000);//CPU省電対策
/* std::vector<void*> v2;
for(i=0;i<10000;i++)
v2.push_back(malloc(100));
*/ t = timeGetTime();
for(j=0;j<10000;j++)
{
std::vector<void*> v;
for(i=0;i<10000;i++) {v.push_back(malloc(100));free(v[i]);}
}
printf("%d\n",timeGetTime()-t);
return 0;
}
>そう。malloc自体になにかある。同じアドレスは速い。
心霊現象かよ。
- 77 :
- >>75
t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
for(i=0;i<100;i++){ v.push_back(malloc(100)); free(v[i]); }
//for(i=0;i<100;i++){ free(0); }
}
printf("%d\n",timeGetTime()-t);
t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
for(i=0;i<100;i++){ v.push_back(malloc(100)); }
for(i=0;i<100;i++){ free(v[i]); }
}
printf("%d\n",timeGetTime()-t);
コメントあり
1082
1327
コメントなし
1120
1334
リリースモード、最適化・全体の最適化なしで。
コメントを外した場合、上のほうがfree(0);のコスト分だけ上乗せされるが、
実際はそれでも勝ってる。この結果はどうする?
- 78 :
- >>76
んな妙なCPU対策しないで、倍率可変切れよ。ブレまくるだろ。
- 79 :
- >>76
>>77のソースのコメントを外し、1番目と二番目を入れ替え、間にさらに10倍した
std::vector<void*> v2;
for(i=0;i<100000;i++) v2.push_back(malloc(100));
を挿入しても
1344
1133
という結果で、多くても誤差範囲だったぞ。
>事前にデータが確保されている数が多いほど、探索に時間がかかる。
いや、stlの2倍ずつ増やすという例はあるが、いくらなんでもそういうアホな実装はしてないだろ・・・
- 80 :
- >>65
たった100程度の配列でも、1ループに付き13回の全要素コピーと、40もの余分な領域が生じるというのに、
実測現れないという曖昧な理由でこれを無視出来るあなたは、ゲームプログラムから手を引くべきだと本気で思います。
- 81 :
- まだやってるのか・・好きに組めばいいでしょ
第一スレチなんで他でやってよ
- 82 :
- >>77
ループの中のコードを変えたらまともに測定出来ないから、
ループの中身をいじらない>>76の検証用のソースを用意したんだが。
まずはその結果に対する反証や、やり方がおかしいという意見は無いのか?
- 83 :
- モチツケ(・∀・)
- 84 :
- >>82
ソースはそのまま、リリース、最適化・全体の最適化ON
事前確保なし 7466
事前確保あり 7187
下二桁はぶれるが数十回測ってもだいたいこんなもん。
事前確保ありのほうが何故か速いが、逆に俺の援護になっちまったんじゃないのか?
- 85 :
- すごいスレがのびてるとおもってたどって見たら俺のレスが起因だった
- 86 :
- >>70
私はこの議論を楽しく読ませてもらってる。
以前にもnew/deleteのコストの議論があったと思うが、あれも面白かった。同じ人かどうかは知らないが。
しかし
>無いものを無いと証明するのは悪魔の証明で不可能だ。
これは間違ってるのでつっこんでおく。ネット上ではこの勘違いがとても多いんだ。
たとえば、「最大の素数」が存在しないことは証明されている。あるいはアリバイというのは「犯行可能な時刻に、犯行可能な場所に存在しなかった証明」に他ならない。
その他諸々、非存在の証明なんて普通にある。
「悪魔の証明」というのは「非存在証明の方が手続きがめんどくさいんだから、存在を確信できる人がいるなら、その確信できる理由を挙げてもらった方が話が早い」という程度の意味だ。
- 87 :
- >>76
探索ってのはアロケートの空き領域探しの事?
そうなら断片化させまくったらメモリ確保の速度が低下する可能性が微レ存?
- 88 :
- >>84
ではこれでどう?
プロセスの優先順位の調整と、回数ごとの揺らぎが分かるように変更。
#include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
timeBeginPeriod(1);
int i,j,k;
for(i=0;i<10000;i++) malloc(1000);
for(k=0;k<10;k++)
{
DWORD t = timeGetTime();
for(j=0;j<10000;j++)
{
std::vector<void*> v;
for(i=0;i<10000;i++){ v.push_back(malloc(100));free(v[i]); }
}
printf("%d:%d\n",k,timeGetTime()-t);
}
return 0;
}
- 89 :
- ちなみに私の環境の結果。
これで環境ごとに結果が逆転するようなら、私の力量では測定用のコードは書けない。
mallocに無駄がなさ過ぎる。
・ダミーメモリ無し
0:5882
1:5639
2:5639
3:5643
4:5621
5:5619
6:5637
7:5628
8:5641
9:5637
・ダミーメモリ有り
0:5770
1:5746
2:5745
3:5736
4:5746
5:5738
6:5749
7:5749
8:5727
9:5731
- 90 :
- >>88
ソースはそのまま、リリース、最適化・全体の最適化ON
・ダミーメモリ無し
0:7833
1:7758
2:7827
3:7884
4:7803
5:7847
6:7854
7:7888
8:7839
9:7809
・ダミーメモリ有り
0:7503
1:7503
2:7500
3:7501
4:7501
5:7501
6:7501
7:7500
8:7502
9:7507
逆転する。が、メモリ確保したほうがえらい安定してる。
そうなると単純にキャッシュの問題ではないような気もする。
キャッシュから引いてるなら差は出ないはずだから。
- 91 :
- おい
Windowsには解放されたメモリ領域をキャッシュする機能はあるって
新しくメモリを確保する時も、以前に同じサイズの領域を確保していたら、そいつとアドレスが入れ替わるとかよくある
reallocでサイズを変更した時は、メモリブロックを移動する必要がある時のみコピーが行われるんだって!常にコピーされるとみなしてコストを計算するのは誤り
お前のプログラムはメモリ確保だけで出来てるのかよw
上限の確実に分かるような配列のみreserve
上限が分からなくとも、頻繁に使う配列はメモリを解放せずサイズを0にして再利用
これで十分だろ気にしすぎ
- 92 :
- 初心者だからわからないんだけど
vectorに一度1000回push_backしたあとclearして
もう一度1000回push_backした時ってすでにメモリが確保されてるから速くなるんだよね?
じゃあゲームで
毎フレームclearしてからオブジェクトをpush_backしまくる設計でも
じきに負荷が軽くなってくんじゃないの?
- 93 :
- >>92
うん
何処かに取っておけば解放されず消えない
- 94 :
- >>91
ごもっとも。俺としてはなんらかのキャッシュがあるというのが真実ならそれでOK。
>>92
なるよ。1000回push_backするとき実装によるが、たしか倍々でreallocするので
拡張できるときは>>91の言うようにコピーのコストはかからない。
最後に無駄なメモリを確保してしまうが、それ以外はreserveを最初にしたのと変わらないよ.。
ただし、push_backするのがintなどならいいが、内部でnewを伴うものを入れるときのコストは結構でかいので
ポインタで持つとか工夫が必要。
- 95 :
- 補足で。
>内部でnewを伴うものを入れるときのコストは結構でかい
ID:+ZBVAlmgに言わせると、誤差範囲なので気にするなと言うだろうw
多少の速度を犠牲にしてもコードの読みやすさを重視するなら選択の一つとしても別に悪くない。
俺の場合はオブジェクトプールを作って、newのオーバーロードで毎フレーム生成してる事が多い。
これなら可読性を損なわず高速化できるし、生newとの比較も簡単にできるしリーク検出にも使えるし
- 96 :
- オブジェクトをそのままいれるようなことはしないよ
たぶん
あと、クラスのコンストラクタで、シングルトンデザインの管理クラスに自身を登録するって設計は、他人からみてわかりやすい?
はたからみると
new CKurasu();
とだけ一行で収められててわかりにくかったりする?
- 97 :
- コメントがしっかりしてればわかるだろうけど、
コンストラクタまで見ないと何をやってるかわからないというのは、こう、ねぇ?
- 98 :
- 外部仕様と例外処理がしっかりしてれば中身なんてどうでもいい
使うのに中身見ないといけなくてしかもクラス間の依存性高かったら舌打ちするかもしれん
- 99 :
- >>98
それもそうか
でもクラス間依存が少ないクラス設計ってどういうの?
テンプレート使うとか?
- 100read 1read
- 1read 100read
TOP カテ一覧 スレ一覧 2ch元 削除依頼 ▲
【Ruby/SDL他】Rubyでゲーム制作・総合スレッド (665)
2chでのゲーム製作を語るスレ 68kb (763)
ゲーム作りってそんなに時間かかるもんなの? (107)
正直、コミックメーカーって、どうよ? (746)
■□■NET Game作ってみない?■□■ (201)
JAVAアプリでゲーム (185)
--log9.info------------------
【キスも】Kiss総合45【プラスも】 (202)
種村有菜ってどう?226 (356)
昭和女子漫画的ボキャブラリー (827)
【あさりちゃん】室山まゆみ総合スレ その11 (423)
萩岩睦美 4 (363)
野間美由紀 26貫目 (864)
【遙かなる時空の中で】水野十子132【誰がため】 (350)
赤ずきんチャチャ 彩花みん 10 (169)
雁須磨子 5 (369)
★神谷悠★迷宮シリーズ他 7 (893)
●ノドアメイカガ 望月花梨9● (246)
風光る●渡辺多恵子49 (684)
【電撃デイジー】最富キョウスケ3【バスローブ黒崎】 (917)
MMMM 水城せとな 25 MMMM (906)
【さよならソルシエ】穂積【式の前日】 (252)
少女漫画界の老害って・・・? (122)
--log55.com------------------
飲食店と煙草 Part.11
秩父にて乳撫
キャピトル鼻煙溜池山王
IQOS総合スレ その8
喫煙者頭おかしいのか あの汚くて臭い煙の何がいいのか
今時嫌煙やってるバカについて語るスレpart7
ソフトバンク社員集まれ(その30)
渋谷パルコ【1】