gpt4 book ai didi

c++ - 我正在尝试面向数据的设计——我可以用 std::vector 来做吗?

转载 作者:行者123 更新时间:2023-11-30 00:56:54 25 4
gpt4 key购买 nike

好的,下面是比较面向对象编程 (OOP) 解决方案与更新一堆球的面向数据设计 (DOD) 解决方案的示例代码。

const size_t ArraySize = 1000;

class Ball
{
public:
float x,y,z;
Ball():
x(0),
y(0),
z(0)
{
}

void Update()
{
x += 5;
y += 5;
z += 5;
}
};

std::vector<Ball> g_balls(ArraySize);

class Balls
{
public:
std::vector<float> x;
std::vector<float> y;
std::vector<float> z;

Balls():
x(ArraySize,0),
y(ArraySize,0),
z(ArraySize,0)
{
}

void Update()
{
const size_t num = x.size();
if(num == 0)
{
return;
}

const float* lastX = &x[num - 1];

float* pX = &x[0];
float* pY = &y[0];
float* pZ = &z[0];
for( ; pX <= lastX; ++pX, ++pY, ++pZ)
{
*pX += 5;
*pY += 5;
*pZ += 5;
}
}
};

int main()
{
Balls balls;

Timer time1;
time1.Start();
balls.Update();
time1.Stop();

Timer time2;
time2.Start();
const size_t arrSize = g_balls.size();
if(arrSize > 0)
{
const Ball* lastBall = &g_balls[arrSize - 1];
Ball* pBall = &g_balls[0];
for( ; pBall <= lastBall; ++pBall)
{
pBall->Update();
}
}
time2.Stop();


printf("Data Oriented design time: %f\n",time1.Get_Microseconds());
printf("OOB oriented design time: %f\n",time2.Get_Microseconds());

return 0;
}

现在,它确实可以在 Visual Studio 中编译和运行,但我想知道我是否被允许这样做,应该能够可靠地做到这一点:

const float* lastX = &x[num - 1];//remember, x is a std::vector of floats

float* pX = &x[0];//remember, x is a std::vector of floats
float* pY = &y[0];//remember, y is a std::vector of floats
float* pZ = &z[0];//remember, z is a std::vector of floats
for( ; pX <= lastX; ++pX, ++pY, ++pZ)
{
*pX += 5;
*pY += 5;
*pZ += 5;
}

根据我的理解,std::vector 中的数据应该是连续的,但我不确定,因为它是如何在内部存储的,如果这在另一个平台上会成为问题,如果它违反了标准.此外,这是我能够使 DOD 解决方案超越 OOP 解决方案的唯一方法,任何其他迭代方法都没有那么好。我可以使用迭代器,尽管我很确定它可能只比启用优化的 OOP 更快,也就是在 Release模式下。

那么,这是执行 DOD 的好方法吗(最好的方法?),这是合法的 c++ 吗?

[编辑]好吧,对于国防部来说,这是一个糟糕的例子; x、y、z 应该打包在 Vector3 中。因此,虽然 DOD 在调试中比 OOP 运行得更快,但在发布中却是另一回事。同样,这不是您希望如何有效使用 DOD 的一个糟糕示例,尽管它确实显示了如果您需要同时访问一堆数据它的缺点。正确使用 DOD 的关键是“根据访问模式设计数据”。

最佳答案

所有代码的问题有点令人费解,所以让我们看看我是否理解您真正需要的东西:

From my understanding the data in a std::vector are supposed to be contiguous

是的。该标准要求 vector 中的数据连续存储,这意味着所有符合该标准的平台/编译器都是这种情况。

this was the only way I was able to get the DOD solution to outdo the OOP solution

我不知道你说的 DOD 是什么意思

I could use iterators, though I'm pretty sure that might only be quicker with optimizations

实际上,这种情况下的迭代器(假设您在 VS 中禁用了调试迭代器)即使不比通过指针直接修改更快也一样快。 vector 中的迭代器可以使用指向元素的普通指针来实现。再次注意,默认情况下 VS 迭代器会做额外的工作来帮助调试。

接下来要考虑的是两种方法的内存布局不同,这意味着如果在稍后阶段您需要访问所有 xyz 来自单个元素,在第一种情况下,它们很可能落在单个缓存行中,而在三个 vector 方法中,它将需要从三个不同的位置提取内存。

关于c++ - 我正在尝试面向数据的设计——我可以用 std::vector 来做吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9298530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com