草庐IT

Android:线程不并行运行

coder 2023-12-04 原文

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

有关Android:线程不并行运行的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  5. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  6. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  7. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

  8. ruby-on-rails - before_filter 运行多个方法 - 2

    是否有可能:before_filter:authenticate_user!||:authenticate_admin! 最佳答案 before_filter:do_authenticationdefdo_authenticationauthenticate_user!||authenticate_admin!end 关于ruby-on-rails-before_filter运行多个方法,我们在StackOverflow上找到一个类似的问题: https://

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

随机推荐