多线程在C++中进行模拟
Multithreading a simulation in C++
我写了一个相当复杂的程序,模拟粒子系统中类似细胞的小生物体的行为。
模拟会经历几个阶段,在这些阶段中,它会为模拟中的每个对象计算下一个位置。模拟中的每个粒子和生物体都会调用一个"运动"成员函数,该函数会更新其位移矢量(在生物体的情况下,它处理AI和运动)。然后,渲染函数遍历每个对象,并在每个对象的新位移处绘制适当的形状。
在渲染帧之前,每个对象的位移计算都要进行数百次,这使得模拟运行得更快。
在这个过程中,在不知道当前位置的情况下(由于过程的串行性),不可能计算对象的下一个位置,所以我不能给几个不同的线程一个"块"帧来计算——每个帧都依赖于前一帧的计算。
正如我之前提到的,每个对象的新位置是通过迭代每个对象并调用当前对象的成员函数来计算的,该函数计算该特定对象的新的位置。我想知道这个过程是否可以并行完成——在一个线程上计算四分之一的对象,在第二个线程上再计算四分之二的对象,等等。这种方法可能吗?当模拟中有大量对象时,它会提高每帧的计算速度吗?
您可能想要使用某种形式的双缓冲:也就是说,您想要一组原始的源状态单元格,以及一组应用程序将计算结果写入其中的单元格。
在处理模拟时,您将从第一个缓冲区读取,并将写入第二个缓冲区。当传球完成时,你交换。
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的消息传递库。
- 如何使用Google Mock来模拟gettimeofday()
- G锁定铸造到基础上会释放模拟行为
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 落砂模拟碰撞检测C++和SFML
- 在gtest.中使用fff.h模拟系统API
- 谷歌模拟和覆盖关键字
- 用C#中的并集模拟C++嵌套结构
- 在同一模拟中使用静脉和静脉_ inet内容时出现运行时错误
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 我写了一个C++程序来模拟Enigma机器.我没有得到输出
- 如何模拟不同边数的骰子滚动?
- 模拟持久按键
- 使用SIR模型的疾病爆发模拟
- 在 c++ 中模拟输入并在 JAVA 中读取它?
- 转发变量参数列表以模拟 std::thread
- 如何在谷歌模拟中匹配 C 样式数组
- 如何使用兰德随机化模拟点击
- 模拟GPS数据,以便使用Qt与Traccar一起使用
- QKeyPress - 在Qt中模拟按键
- 如何使用不同的谷歌模拟运行相同的谷歌测试用例?