首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Android:线程不能并行运行

Android:线程不能并行运行
EN

Stack Overflow用户
提问于 2012-12-11 02:25:56
回答 2查看 2.3K关注 0票数 6

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

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

查看url,因为我没有镜像权限:http://img849.imageshack.us/img849/9688/capturegff.png

这些线程似乎不会同时执行代码。我将world线程初始化为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class World implements Runnable {

    Thread thread;

    public World(...) {
    ...
        // Initialise the player/ball objects
        initialiseObjects();

        thread = new Thread(this, "World");
        thread.start();
}
}

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    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
    }

我不明白上面的代码如何导致线程的顺序执行,尽管我以前从未尝试过多线程,所以我可能做了一些根本错误的事情。我试图加快游戏的速度,但它明显变慢了,而且不那么流畅了。你知道为什么线程不能并行运行吗?

更新:问题是我手机的处理器只有一个内核。我确信令人难以置信的S是双核的,但遗憾的是它只有一个。我在S2上试过了,它确实是并行运行线程的。

然而,如果市场上只有较新的手机支持多线程,那么它的优势是什么呢?我不明白副本岛如何通过实现多线程在旧的单核手机上实现更好的性能。如果没有第二个内核可以利用,那么线程间同步的额外开销肯定会导致性能降低吗?

多线程导致了单核上的性能下降,因为必须生成缓冲区,然后将缓冲区传递给绘图线程。在双核上,它快了5-10%,尽管在大约500个精灵中,由于缓冲区的原因,更新周期再次比绘制周期更长,从而限制了速度的提高。显然,通过优化我可以改进这一点,但问题是,是否值得以牺牲单核处理器为代价来支持多线程。有没有可能确定手机的处理器,以便在运行时确定是否使用多线程?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-04 04:40:30

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

通知运行时线程已完成的一种方法是调用Thread.yield。你的代码中有一个繁忙的循环,这对你的情况没有帮助。它让CPU忙个不停,什么都不做。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
while(otherBuffer.isFinished() == false)

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

票数 3
EN

Stack Overflow用户

发布于 2013-01-04 05:10:51

创建线程,如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Threadcalling implements Runnable
    {

        @Override
        public void run() {
}
}

所以使用下面这样的方法来命名它

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Thread t=new Thread(new Threadcalling ());
                  t.start();

您可以创建许多这样的线程类,并将其称为并行。这不会有任何问题。好好工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13812670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文