我正在用 Android/OpenGL 编写游戏,并试图通过在各自的线程上运行每个逻辑来将我的 OpenGL(渲染)逻辑与我的游戏更新逻辑分开,以提高性能。
我设法让每个线程都在自己的线程上运行,但是根据 DDMS 中的 Tracer,线程仍在按顺序运行(world 是我的游戏更新线程):
请查看 url,因为我没有图片权限: http://img849.imageshack.us/img849/9688/capturegff.png
线程似乎没有同时执行代码。 我按如下方式初始化世界线程:
public class World implements Runnable {
Thread thread;
public World(...) {
...
// Initialise the player/ball objects
initialiseObjects();
thread = new Thread(this, "World");
thread.start();
}
}
我已经在两个线程之间实现了自己的同步。使用类似于 Replica Island 中的方法,我有两个渲染缓冲区:更新线程(理想情况下应该)写入其中一个缓冲区,而渲染线程正在读取另一个缓冲区。缓冲区包含渲染器绘制每个 Sprite 所需的信息。一旦更新线程完成更新其缓冲区并且渲染器完成绘制,它们就会交换缓冲区并重复该过程。
在游戏更新线程的代码中(渲染线程中的类似代码):
currBuffer.write();
player.draw(currBuffer.getNext());
ball.draw(currBuffer.getNext());
if (particleEffect != null) {
particleEffect.draw(currBuffer);
}
currBuffer.finished();
while(otherBuffer.isFinished() == false) {
//otherBuffer is finished once the render thread has finished drawing
}
DrawBuffer tempBuffer = currBuffer;
currBuffer = otherBuffer;
otherBuffer = tempBuffer;
currBuffer.changed();
while(otherBuffer.isChanged() == false) {
//otherBuffer is changed once the render thread has also swapped buffered
}
我看不出上面的代码如何导致线程的顺序执行,尽管我以前从未尝试过多线程,所以我可能做的事情根本上是错误的。我试图加快游戏速度,但它明显变慢了,而且流畅度大大降低。知道为什么线程不并行运行吗?
更新: 问题是我手机的处理器只是单核。我确信 Incredible S 是双核的,但可惜它只是单核。我在 S2 上试过了,它确实并行运行了线程。
但是,如果只有市场上较新的手机才支持,那么多线程的优势是什么?我不明白 Replica Island 如何通过实现多线程在旧的单核手机上管理更好的性能。如果没有第二个核心可以利用,线程间同步增加的开销肯定会导致性能下降吗?
多线程导致单核性能降低,因为必须生成缓冲区,然后传递给绘图线程。在双核上,速度提高了 5-10%,尽管在大约 500 个 Sprite 时,由于缓冲区的原因,更新周期比绘制周期再次花费更长的时间,从而限制了速度增益。显然,通过优化我可以改进它,但问题是是否值得以牺牲单核处理器为代价来支持多线程。是否可以确定手机的处理器以便在运行时确定是否使用多线程?
最佳答案
嗯,从技术上讲,1 个 CPU 一次只能运行一个代码段。你的OS scheduler在几分之一毫秒内更改进程/线程,让您产生同时运行多个进程的错觉。
一种通知运行时您的线程现在已完成的方法是调用 Thread.yield .您的代码中有一个繁忙的循环,这对您的情况没有帮助。它让 CPU 忙于不做任何事情。
while(otherBuffer.isFinished() == false)
你应该使用Loks而不是繁忙的循环,或者您可以尝试在 while 循环中调用 Thread.yield
以提高初始性能。顺便说一句,也看看semaphore这是此类生产者-消费者问题的最简单解决方案。如果您想保留当前的代码库,可以为每个缓冲区使用一个锁。
关于Android:线程不并行运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13812670/