【问题标题】:Is there a point in memory on the stack where performance drops significantly?堆栈上的内存中是否存在性能显着下降的点?
【发布时间】:2015-01-08 13:45:15
【问题描述】:

在堆栈上的内存分配量中是否存在性能显着下降的点?我知道如果它在堆上,当你的内存从 L1 移动到 L2 再到主内存时,缓存未命中的数量会急剧增加,但是堆栈呢?

在注释掉所有其他函数之后,在我个人的示例中,(游戏引擎)并专注于在每个对象的每一帧上调用这行代码:

    image.getTrans().x += velocity[VELOCITY_X];
    image.getTrans().y += velocity[VELOCITY_Y];

在从 0 个对象到 1500 个对象(我发现它本身对于很少的东西来说很大)之后,fps 从大约 2000 fps200 fps 以恒定的速率下降,但是在添加大约 50 或 100 个对象之后对象越多,fps 会下降到 60 fps50 fps,而不是下降到 2 fps1 fps,添加更多后会更糟。

这里所做的只是将velocity[type](在堆栈上)添加到图像的transformation.type(也在堆栈上)。

由于现代计算机每秒可以运行如此荒谬的计算量(我相信大约 360 亿次),我在这里能想出的唯一解决方案是,大部分时间,程序都在等待内存,我无法理解,因为这些都在堆栈上。

抱歉,这里有任何遗漏的术语或遗漏的解释,我对很多与记忆有关的想法都比较陌生

【问题讨论】:

  • 范围太广,无法诊断出实际的问题。个人资料。
  • 堆栈也驻留在 RAM 中。
  • 您的假设不正确。堆栈/堆与 L1/L2 缓存几乎没有关系——局部性和预取是的,堆栈/堆没有。鉴于这种程度的误解,您对自己代码的分析几乎没有可靠性。抱歉,当我只能看到雾时,我很难提供帮助。
  • 算一下。在要处理的零对象时,您有 2000 fps。在 1500 个对象时,您的速率会降低到 200fps。这可能是因为您需要处理更多数据吗?

标签: c++ performance memory stack


【解决方案1】:

首先,很少有编译器或程序在 L1、L2 或 L3 缓存中分配内存。简单的原因是他们不知道地址。此外,L1、L2 和 L3 高速缓存的大小比主存储器小很多。

一般来说,堆栈的容量与性能关系不大。堆栈的容量通常是函数调用嵌套或递归的限制,或者是可以存储的局部变量的数量。

如果堆栈内存向堆方向增长,则在堆栈空间不足(并与堆冲突)或堆增长并覆盖堆栈时可能会遇到问题。

堆栈内存的分配通常是增加堆栈指针的值。最坏的情况,这涉及将值从内存加载到寄存器,调整寄存器中的值,然后存储回内存,3 次操作。

您的程序可能会因数组大小的增加而受到比堆栈分配更大的影响。数组越大,对其执行的迭代越多。每次迭代都会打断处理器的数据处理周期,浪费时间。

如果您的数据组织正确且大小正确,处理器可能会将所有数据拖入其缓存中。如果我们假设当处理器从内存中获取数据并放入缓存时,它不会加载一个变量。最有可能的是,处理器引入了足够的数据来填充一个或多个高速缓存行。如果您的阵列适合高速缓存行,则处理器会将您的所有数据都放在其高速缓存中,并带有该负载。如果您正在访问彼此不相邻的阵列插槽,处理器可能必须重新获取不同的内存,从而擦除您现有的数据(从而降低性能)。

阅读这些主题:

  • 优化缓存性能。
  • 数据驱动设计
  • 优化数据缓存性能

与往常一样,分析您的代码以找出瓶颈。有时,设计更改可能比简单的代码更改具有更高的投资回报率。

【讨论】:

  • 将“SRAM”更改为“主存储器”。 L1、L2 和 L3 实际上是 SRAM,而主存储器不是(它是 DRAM)。
  • 在我的嵌入式系统上,SRAM 是主存储器。我不知道我们的 ARM7 SOC 用于缓存的技术。我们没有 DRAM。
  • 这相当罕见,但仍然:术语“主内存”涵盖系统中的主 SRAM(但不包括其缓存 SRAM)和 Cortex-A、x86 使用的常见 DRAM 主内存、x64、POWER、SPARC 等
猜你喜欢
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 2020-03-23
  • 2011-03-05
  • 2016-10-11
  • 2014-10-03
  • 1970-01-01
  • 2011-02-11
相关资源
最近更新 更多