我开始了一些面向数据的设计实验。我最初开始做一些 oop 代码,发现有些代码非常慢,不知道为什么。这是一个例子:我有一个游戏对象
class GameObject
{
public:
float m_Pos[2];
float m_Vel[2];
float m_Foo;
void UpdateFoo(float f){
float mag = sqrtf(m_Vel[0] * m_Vel[0] + m_Vel[1] * m_Vel[1]);
m_Foo += mag * f;
}
};
然后我使用 new 创建 1,000,000 个对象,然后循环调用 UpdateFoo()
for (unsigned i=0; i<OBJECT_NUM; ++i)
{
v_objects[i]->UpdateFoo(10.0);
}
完成循环大约需要 20 毫秒。当我注释掉float m_Pos[2]的时候发生了奇怪的事情,所以对象看起来像这样
class GameObject
{
public:
//float m_Pos[2];
float m_Vel[2];
float m_Foo;
void UpdateFoo(float f){
float mag = sqrtf(m_Vel[0] * m_Vel[0] + m_Vel[1] * m_Vel[1]);
m_Foo += mag * f;
}
};
突然循环需要大约 150 毫秒才能完成。如果我在 m_Vel 之前放任何东西,速度会快得多。我尝试在 m_Vel 和 m_Foo 或其他地方之间放置一些填充,除了 m_Vel 之前的地方......慢。
我在发布版本中测试了 vs2008 和 vs2010,i7-4790 知道这种差异是如何发生的吗?它是否与任何缓存一致的行为有关。
这是整个样本:
#include <iostream>
#include <math.h>
#include <vector>
#include <Windows.h>
using namespace std;
class GameObject
{
public:
//float m_Pos[2];
float m_Velocity[2];
float m_Foo;
void UpdateFoo(float f)
{
float mag = sqrtf(m_Velocity[0] * m_Velocity[0] + m_Velocity[1] *
m_Velocity[1]);
m_Foo += mag * f;
}
};
#define OBJECT_NUM 1000000
int main(int argc, char **argv)
{
vector<GameObject*> v_objects;
for (unsigned i=0; i<OBJECT_NUM; ++i)
{
GameObject * pObject = new GameObject;
v_objects.push_back(pObject);
}
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);
for (unsigned i=0; i<OBJECT_NUM; ++i)
{
v_objects[i]->UpdateFoo(10.0);
}
QueryPerformanceCounter(&nEndTime);
double dWasteTime = (double)(nEndTime.QuadPart-
nBeginTime.QuadPart)/(double)nFreq.QuadPart*1000;
printf("finished: %f", dWasteTime);
// for (unsigned i=0; i<OBJECT_NUM; ++i)
// {
// delete(v_objects[i]);
// }
}