2012-12-11 51 views
6

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

我设法在自己的线程运行的每一个,但是根据在DDMS示踪,线程仍在运行顺序(世界是我的游戏更新线程):

查看网址,因为我不有图像特权:螺纹似乎 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(); 
} 
} 

我实现了两个线程之间我自己的同步。使用类似于副本岛的方法,我有两个呈现缓冲区:更新线程(理想情况下)在呈现线程正在读取另一个缓冲区时写入其中一个缓冲区。缓冲区包含渲染器绘制每个精灵所需的信息。一旦更新线程完成更新其缓冲区并且渲染器已完成绘图,它们交换缓冲区并重复该过程。

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

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

+0

如果您只有一个内核,并且这两个任务都受CPU限制,那么他们确实无法并行运行。另外,这些'while'循环里面有什么?他们真的是空循环吗? –

+0

谢谢@David Schwartz - 确实是这个问题。我确定Incredible S是双核心,但是它只是单一核心。我在S2上试了一下,它确实并行地运行了线程。但是,如果只有市场上的新手机支持它,那么多线程的优势是什么呢?我不明白Replica Island如何通过实现多线程技术在较老的单核手机上实现更好的性能。当然,如果没有第二个内核可以利用,线程间同步的额外开销会导致性能下降? – awr

+0

如果这些任务不受CPU限制,那么多线程可能会带来巨大的好处。如果一项任务无法取得进展(比如说因为它正在等待I/O),另一项任务可以。但是,如果只有一个内核,并且您的任务受CPU限制,则多线程无法提供帮助。 –

回答

3

从技术上讲,1个CPU一次只能运行一个代码段。您的OS scheduler会在几毫秒内更改进程/线程,这会让您错觉同时运行多个进程。

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

while(otherBuffer.isFinished() == false) 

你应该使用Loks而不是繁忙的循环或者你可以尝试调用Thread.yield,虽然循环内的初始性能提升。顺便说一句,也看看semaphore这是这种生产者 - 消费者问题的最简单的解决方案。如果您想保留当前的代码库,则可以使用每个缓冲区的锁定。

0

像下面

class Threadcalling implements Runnable 
    { 

     @Override 
     public void run() { 
} 
} 

使用像下面

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

您可以创建多线程类这样的,并称之为平行这样称呼它创建一个线程中类。它不会使任何probs。工作得很好。