Android:线程不并行运行

标签 android multithreading opengl-es-2.0

我正在用 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/

相关文章:

java - 如何将两个android studio项目合并为一个

java - 在同一 Activity 中从工具栏搜索 View 获取查询字符串?

c++ - ZMQ 导致主线程卡住(或类似的东西..?)

java - 安卓OpenGL ES 2.0 : Text aren't showing up

java - Triangle_Strip 应该包裹吗?

android - Gradle:compileOnly 和 runtimeOnly

java - 将 json 部分反序列化为 POJO,但保留一些原始 json 作为字段

java - 当池中仍有线程运行时,为什么 executor.isShutdown() 返回 true?

java - 在多用户聊天 Android 客户端中使用 AsyncTask 是否比扩展连接线程更好?

ios - Cocos2d:在运行时为Sprite节点中批处理的CCSprite设置zOrder似乎无效