6

我正在用 Android/OpenGL 编写游戏,并试图将我的 OpenGL(渲染)逻辑与我的游戏更新逻辑分开,通过在自己的线程上运行每个以提高性能。

我设法让每个线程都在自己的线程上运行,但是根据 DDMS 中的 Tracer,线程仍在按顺序运行(世界是我的游戏更新线程):

请参阅网址,因为我没有图像权限: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 的方法,我有两个渲染缓冲区:更新线程(理想情况下应该)写入其中一个缓冲区,而渲染线程正在读取另一个缓冲区。缓冲区包含渲染器绘制每个精灵所需的信息。一旦更新线程完成更新其缓冲区并且渲染器完成绘制,它们交换缓冲区并重复该过程。

在游戏更新线程的代码中(渲染线程中的类似代码):

    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 个精灵时,由于缓冲区的原因,更新周期再次比绘制周期花费了更长的时间,从而限制了速度增益。显然,通过优化我可以改善这一点,但问题是是否值得以牺牲单核处理器为代价来支持多线程。是否可以确定手机的处理器以便在运行时确定是否使用多线程?

4

2 回答 2

3

好吧,从技术上讲,1 个 CPU 一次只运行一个代码段。您的操作系统调度程序会在几毫秒内更改进程/线程,这让您产生同时运行多个进程的错觉。

通知运行时您的线程现在已完成的一种方法是调用Thread.yield。您的代码中有一个繁忙的循环,这对您的情况没有帮助。它使 CPU 忙于不做任何事情。

while(otherBuffer.isFinished() == false)

您应该使用Loks而不是忙循环,或者您可以尝试Thread.yield在该 while 循环内调用以提高初始性能。顺便说一句,还要看看信号量,它是解决此类生产者-消费者问题的最简单解决方案。如果要保留当前的代码库,可以对每个缓冲区使用一个锁。

于 2013-01-04T04:40:29.843 回答
0

像下面的类一样创建线程

class Threadcalling implements Runnable
    {

        @Override
        public void run() {
}
}

所以像下面这样调用它

Thread t=new Thread(new Threadcalling ());
                  t.start();

您可以像这样创建许多线程类并将其称为并行。它不会产生任何问题。运作良好。

于 2013-01-04T05:10:50.970 回答