为了账号安全,请及时绑定邮箱和手机立即绑定

通过使用多个线程/内核来提高性能

通过使用多个线程/内核来提高性能

呼如林 2022-01-05 20:35:39
我有一个游戏(使用 pygame),我想提高其性能。我注意到当我的 fps 较低时,游戏最多只使用 20% 的 CPU,有没有办法可以使用线程来使用更多的 CPU?我已经尝试实现线程,但似乎运气不佳,将不胜感激。此功能是导致滞后的原因:第一版def SearchFood(self):    if not self.moving:        tempArr = np.array([])        for e in entityArr:            if type(e) == Food:                if e.rect != None and self.viewingRect != None:                    if self.viewingRect.colliderect(e.rect):                        tempArr = np.append(tempArr, e)        if tempArr.size > 0:            self.nearestFood = sorted(tempArr, key=lambda e: Mag((self.x - e.x, self.y - e.y)))[0]第二个版本(较慢)def SearchFood(self):    if not self.moving:        s_arr = sorted(entityArr, key=lambda e: math.hypot(self.x - e.x, self.y - e.y))        for e, i in enumerate(s_arr):            if type(e) != Food:                self.nearestFood = None            else:                self.nearestFood = s_arr[i]                break我查看整个实体列表,并在实体是食物以及与想要吃所述食物的事物的距离之后对其进行排序。问题是实体数组有 500 个元素(甚至更多),因此需要很长时间进行迭代和排序。然后为了弥补我想通过使用线程来利用更多的 CPU。如果有帮助,这里是完整的脚本:https : //github.com/Lobsternator/Game-Of-Life-Esque.git
查看完整描述

2 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

在 Python 中,线程不会增加使用的核心数。您必须改用多处理。
文档:https : //docs.python.org/3.7/library/multiprocessing.html#multiprocessing.Manager

查看完整回答
反对 回复 2022-01-05
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

Python 中的多线程几乎是无用的(对于像这样的 CPU 密集型任务),并且多处理虽然可行,但需要在进程之间进行昂贵的数据编组或精心设计。我不相信任何一种都适用于您的情况。

但是,除非您的游戏中有大量对象,否则您不需要为您的场景使用多个内核。这个问题似乎更像是算法复杂性。

您可以通过多种方式提高代码的性能:

  • 按类型保留实体索引(例如,从实体类型到实体集的字典,您在创建/删除实体时更新该索引),这将使您无需扫描所有实体即可轻松找到所有“食物”实体游戏。

  • 使用简单的“最小”操作(即O(n))而不是按距离(即O(n*logn))对所有食物进行排序来查找最近的食物实体。

    • 如果这仍然很慢,您可以应用剔除技术,首先将食物过滤到易于计算的范围内(例如玩家周围的矩形),然后通过仅对那些应用更昂贵的距离计算来找到最近的食物。

  • 通过避免检查循环内部不必要的条件,并尽可能使用内置的选择/创建结构,而不是遍历大型对象列表,从而使循环更紧密。

例如,您最终会得到类似的结果:

def find_nearest_food(self):

  food_entities = self._entities_by_type[Food]

  nearest_food = min(food_entities, key=lambda entity: distance_sq(self, entity))

  return nearest_food


def distance_sq(ent1, ent2):

  # we don't need an expensive square root operation if we're just comparing distances

  dx, dy = (ent1.x - ent2.x), (ent1.y - ent2.y)

  return dx * dx + dy * dy

您可以通过将实体位置保持为 NumPy 向量而不是单独的x和y属性来进一步优化,这将允许您使用 NumPy 操作来计算距离,例如distance_sq = (ent1.pos - ent2.pos)**2或仅np.linalg.norm用于常规距离计算。这对于其他向量算术运算也可能有用。


查看完整回答
反对 回复 2022-01-05
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信