我编写了一个相当复杂的程序来模拟粒子系统中类似小细胞的生物的行为。
仿真经历了几个阶段,计算了仿真中每个对象的下一个位置。在模拟中,每个粒子和有机体都需要一个“运动”成员函数,以更新其位移矢量(在生物体的情况下,它处理AI和运动)。然后,呈现函数遍历每个对象,并在每个对象的新位移处绘制适当的形状。
每个物体的位移计算是在渲染一个框架之前进行几百次,这使得模拟运行得更快。
在此过程中,如果不知道当前位置(由于进程的串行性质),就不可能计算对象的下一个位置,因此我不能给出一个“帧”块来计算几个不同的线程--每个帧依赖于前一个线程的计算。
如前所述,每个对象的新位置是通过迭代每个对象并调用当前对象的成员函数来计算的,该成员函数计算该特定对象的新位置。我想知道这个过程是否可以并行进行--计算一个线程上的四分之一对象,另一个线程上的另一个四分之一等等。这种方法可行吗?当模拟中有大量的对象时,它是否能提高每个帧的计算速度?
发布于 2013-12-01 08:29:56
您可能希望使用某种形式的双缓冲:也就是说,您需要一组单元格,它们是您的原始源状态,以及一组单元格,应用程序将计算结果写入其中。
当您处理模拟时,您将从第一个缓冲区读取并写入第二个缓冲区。当传递完成后,您可以交换。
typedef World Cell[9][9]; // World is a 9x9 matrix of Cells
World buffers[2]; // 2 buffers.
World* src = buffers[0];
World* dst = buffers[1];
PopulateWorld(src);
while (running) {
PerformTransformations((const World*)src, (/*!const*/ World*)dst);
std::swap(src, dst);
}
或者,您可以将每个单元格的可转换属性封送/封装到它们自己的结构/类中,这样每个单元格都有一对,您只需在两者之间交换即可。
struct Cell {
struct Data {
Matrix3d position;
Matrix3d velocity;
};
Data m_data[2];
static void DetermineWhichBuffersToUse(size_t runNo, size_t& srcNo, size_t& dstNo) {
// when runNo is even, use m_data[0] as src,
// when runNo is odd, use m_data[1] as src.
size_t src = (runNo & 1);
size_t dst = 1 - src
}
...
};
另一种选择是使用消息传递管道,通过该管道将所有单元格编组成处理数据的请求,由工作线程完成计算,这些线程会将带有结果数据集的消息输出回父线程。
父线程发送所有消息,然后返回所有结果并写入它们。如果您计划在多个系统之间扩展模拟,则此解决方案更值得研究,在这种情况下,您可能希望查看消息传递库中的ZeroMQ之类的内容。
https://stackoverflow.com/questions/20309522
复制相似问题