我的应用程序由两个线程:如何存储和推送模拟状态,同时对每秒更新产生的影响最小?
- GUI线程(使用Qt)
- 模拟螺纹
我使用两个线程的原因是为了保证GUI作出响应,同时让辛线程尽可能快地旋转。
在我的GUI线程中,我以30-60的FPS渲染SIM中的实体;然而,我希望我的模拟器能够“前方紧缩” - 可以这么说 - 并且排队等待最终绘制的游戏状态(认为流式视频,你有一个缓冲区)。
现在对于我渲染的每个帧,我需要相应的模拟“状态”。所以,我的SIM线程看起来像:
while(1) {
simulation.update();
SimState* s = new SimState;
simulation.getAgents(s->agents); // store agents
// store other things to SimState here..
stateStore.enqueue(s); // stateStore is a QQueue<SimState*>
if(/* some threshold reached */)
// push stateStore
}
SimState
样子:
struct SimState {
std::vector<Agent> agents;
//other stuff here
};
与仿真:: getAgents样子:
void Simulation::getAgents(std::vector<Agent> &a) const
{
// mAgents is a std::vector<Agent>
std::vector<Agent> a_tmp(mAgents);
a.swap(a_tmp);
}
的Agent
š本身是比较复杂的类。成员是一堆int
s和float
s和两个std::vector<float>
s。
使用这个当前设置,sim不能紧缩必须比GUI线程绘制得更快。我已经验证目前的瓶颈是simulation.getAgents(s->agents)
,因为即使我没有推出,每秒更新速度也很慢。如果我评论这一行,我会看到每秒更新次数有几个数量级的提高。
那么,我应该用什么种类的容器来存储模拟状态?我知道atm上有一堆拷贝,但其中一些是不可避免的。我应该将Agent*
存储在向量中而不是Agent
?在现实中,模拟不是循环的,而是使用Qt的QMetaObject::invokeMethod(this, "doSimUpdate", Qt::QueuedConnection);
,所以我可以使用信号/插槽在线程之间进行通信;不过,我已使用while(1){}
验证了更简单的版本,问题仍然存在。
我很想知道你是如何解决这个问题的,尽管它可能已经有一段时间了。我遇到类似的问题 – woosah 2015-03-02 03:11:11