如何在一次内存操作中加载可能的最大整数?

时间:2013-04-06 06:01:20

标签: c caching portability low-level stdint

我正在构建一个小型字节码虚拟机,可在各种平台上运行,包括异国情调的嵌入式和微控制器环境。

我的VM中的每个操作码都可以是可变长度(不超过4个字节,不少于1个字节)。在解释操作码时,我想为当前的操作码创建一个微小的“缓存”。但是,由于它在许多不同的平台上使用,很难做到。

所以,这里有一些预期行为的例子:

  1. 在具有8位内存总线的8位微控制器上,我希望它只加载1个字节,因为它需要多个(慢)内存操作才能加载,理论上,它可能只需要1个字节来执行当前操作码
  2. 在8086(16位)上,我想加载2个字节,因为只加载1个字节,我们基本上会抛出一些有用的数据,以便稍后读取,但我不想加载超过2个字节,因为它需要多次操作
  3. 在32位ARM处理器上,我想加载4个字节,因为否则我们要么丢弃可能需要再次读取的数据,要么我们正在进行多个操作
  4. 我想说这可以通过假设unsigned int足够好来轻松处理,但在8位AVR微控制器上,int定义为16位,但内存数据总线宽度仅为8位,因此需要进行2次内存加载操作。

    无论如何,目前的想法:

    使用uint_fast16_t似乎在大多数平台上都能正常工作(ARM上为32位,8086上为16位,x86-64上为64位)。但是,它显然仍然没有AVR和其他8位微控制器。

    我认为使用uint_fast8_t可能会有效,但它会出现在大多数平台上,它被定义为unsigned char,这绝对不是最佳的

    此外,还有另一个问题必须解决:未对齐的内存访问。在x86上,这可能不会成为一个问题(理论上它会做2个内存操作,但它可能在硬件中缓存),但是在ARM上我知道做一个未对齐的32位访问可能花费3倍作为就像单个对齐的32位负载一样。如果地址未对齐,我想加载对齐的选项并获得尽可能多的数据,但不惜一切代价避免另外的内存操作

    有没有办法以某种方式使用魔法预处理器包含或某些方法来执行此操作,还是只需要在编译平台之前手动定义最佳缓存大小?

1 个答案:

答案 0 :(得分:0)

使用标准C提供的类型或信息(在诸如此类的标题中)没有自动的方法来执行此操作。

有时通过在目标平台上执行和测量示例代码并使用结果来确定在实践中使用的代码来处理此类问题。样本可以在构建期间执行,然后构建到最终代码中,也可以在每个程序执行开始时执行,然后用于执行期间。