gpt4 book ai didi

multithreading - 使用 pthread 对 Box2D 进行线程化

转载 作者:行者123 更新时间:2023-12-04 08:28:06 24 4
gpt4 key购买 nike

所以我本质上是在尝试实现一个 AIR Native Extension,它通过 Actionscript 使用 C 语言进行物理模拟。

我已经经历了相当多的迭代,为了兴趣,我将在下面列出这些迭代,我认为这可能是我以更高效的方式使其工作的最后一次尝试。

最终,我正在寻求有关如何设置线程环境的帮助,以便在单独的线程上运行 Box2D 的模拟,然后轮询 AS3 中的状态。

方法:

  • 蛮力:

  • 在这种方法中,我只是从 AS3 调用 C 并告诉它创建一个世界并向它传递一些框以添加到这个世界。 AS3 中的每一帧,我调用 C 来告诉世界 Step,然后遍历世界中的所有物体,获取它们的位置和旋转,将它们转换为 Action 对象并将它们放在 Action 数组中,然后将其发送回AS3。到达那里后,我遍历返回的数组并将这些位置和旋转值分配给我的 Sprite ,以便它们在视觉上更新。

    结果实际上相当不错,在帧率受到影响之前添加了大约 116 个框。这与纯 AS3 实现中的 30 个盒子进行了比较。请注意,这些统计信息处于 Debug模式。在 Release模式下,它们都达到了大约 120 个盒子。 AS3 实现和 Native Extension 实现之间几乎没有区别。
  • ByteArray 分享

  • 为了提高性能,我决定尝试限制跨 C 和 AS3 编码的数据量是个好主意。 ANE 支持共享字节数组的内存空间,因此我会将在 AS3 中创建的 ByteArray 发送到 C 并让 C 简单地更新 ByteArray。这使我们不必在 C 中构造 AS3 对象并将它们传回。每一帧,AS3 只需要遍历它的 ByteArray 并查看 C 写入的内容,然后将这些值分配给 Sprite 以设置视觉状态。

    可悲的是,这里的结果大致相同。改进只是微不足道的。
  • 来自 C 的直接对象设置

  • ANE 能够做的另一件事是设置位于 AS3 中的对象的属性。从这个意义上说,我的目标是消除将数据传回 AS3、循环体以在 C 中收集数据以及在 AS3 中循环以分配值的开销。我直接修改了 Box2D 代码,这样当它的值改变时,它会直接在相应的 Sprite 上写入新的 x、y、旋转值。

    由于设置这些属性的调用不到一毫秒,因此在非常少量的对象时结果令人惊讶。问题是这会线性扩展,大约有 90 个左右的对象,开销太大,事情开始变慢。
  • 线程

  • 说到这里,我有些不知所措。在编码数据方面存在开销,在 C 中存在用于迭代和构造要返回的数据的成本,并且在 AS3 中存在用于迭代以将值分配给 Sprite 的成本。

    显然需要权衡,所以我目前的解决方案是我现在能想出的最好的。

    在 AS3 端,您调用 C 来创建您的世界,调用以向该世界添加一个框,然后调用告诉 C 您想要刷新数据。当在 AS3 中创建 box 时,它们会获得一个唯一的 id,并将它们存储在字典中,键是 id。

    在 C 端,创建世界并生成一个新的 pthread 来执行 Step。本质上是在另一个线程上模拟世界。在它执行之后,它组装所有数据并将其写入一个双数组。然后它一次又一次地这样做。它只是在它自己的线程上永远模拟。

    当我们调用 C 添加一个新盒子时,我需要创建一个新盒子并将其添加到那个世界中。由于世界正在步进,这可能会导致问题,这意味着我很确定我需要使用互斥锁。

    当我们调用以在 AIR 中刷新值时,同样的事情,我想从 double 数组中执行 memcpy 到我的 AS3 字节数组中,然后循环遍历字节数组以设置视觉对象上的值。

    互斥体给我带来了麻烦,所以我基本上实现了我自己的,你可以在下面看到......并 mock :)

    但是它确实有效,只是没有我想要的那么快。大约 90 时,我们又放慢了速度。

    任何人有任何想法或指示?不胜感激!

    C 代码

    解析器正在运行,所以我把它贴在这里:
    http://pastebin.com/eBQGuGJX

    AS3 代码

    解析器也是一样。我只包含了处理 AS3 中每一帧的相关方法。
    http://pastebin.com/R1Qs2Tyt

    最佳答案

    我忘了我有这个问题。幸运的是我已经想通了。

    使用互斥锁等的想法首先是过度设计的,并且是不必要的。

    因为我们在 Flash 中运行,所以一切都在主线程中运行。这意味着对于每个“帧”flash 将 native 处理任何媒体,然后是我们编写的客户端代码,然后实际渲染到屏幕上,最后在必要时进行任何垃圾收集。

    我实际上不需要永远模拟物理模拟,我只需要让它比我的客户端代码领先一步。

    所以现在发生的事情是,当客户端调用 ANE 来设置世界时,它会创建一个新线程来模拟世界并立即返回到 Flash。 Flash 将继续执行其余的客户端代码,然后进行渲染和 GC。

    然后在 Flash 中的每一帧上,我们可以简单地调用 ANE 来检索结果。在模拟线程没有完成的情况下,我们通过连接等待,提取值并将它们返回给 Flash。确保在返回之前为下一步生成另一个线程。

    通过这种方式,我们最大限度地提高了效率,因为模拟是在 Flash 忙于其他我们无法控制的事情(如渲染和 GC)时进行的。

    好消息是这种方法的性能几乎翻了一番。从同步纯 AS3 实现中的大约 90 个盒子到线程 ANE 方法中的大约 170 个盒子。

    瓶颈最终成为通过从 ANE 返回的数据并将这些值分配给显示对象的迭代。

    我希望这可以帮助其他正在寻找类似内容的人。我将在 4 月底在多伦多 FITC 上发表演讲,因此届时我可能会发布更多信息和 Material 。

    http://www.fitc.ca/events/presentations/presentation.cfm?event=124&presentation_id=1973

    关于multithreading - 使用 pthread 对 Box2D 进行线程化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9527423/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com