我正在构建一个小型字节码 VM,它将在各种平台上运行,包括异国情调的嵌入式和微控制器环境。
我的 VM 中的每个操作码都可以是可变长度的(不超过 4 个字节,不少于 1 个字节)。在解释操作码时,我想为当前操作码创建一个微小的“缓存”。但是,由于它在许多不同的平台上使用,所以很难做到。
因此,这里有一些预期行为的示例:
- 在具有 8 位内存总线的 8 位微控制器上,我希望它只加载 1 个字节,因为它需要多个(慢速)内存操作才能加载,理论上,它可能只需要 1 个字节即可执行当前操作码
- 在 8086(16 位)上,我想加载 2 个字节,因为只加载 1 个字节,我们基本上会扔掉一些有用的数据以供以后读取,但我不想加载超过 2 个字节,因为需要多次操作
- 在 32 位 ARM 处理器上,我想加载 4 个字节,因为否则我们要么抛出可能必须再次读取的数据,要么我们正在执行多个操作
我想说这可以通过假设它unsigned int
足够好来轻松处理,但是在 8 位 AVR 微控制器上,int 定义为 16 位,但内存数据总线宽度仅为 8 位,因此 2 个内存加载操作将是必需的。
无论如何,目前的想法:
usinguint_fast16_t
似乎在大多数平台上都能正常工作(ARM 上 32 位,8086 上 16 位,x86-64 上 64 位)。然而,它显然仍然遗漏了 AVR 和其他 8 位微控制器。
我认为 usinguint_fast8_t
可能会起作用,但它会出现在它被定义为 is 的大多数平台上unsigned char
,这绝对不是最佳的
此外,还必须解决另一个问题:未对齐的内存访问。在 x86 上,这可能不会成为问题(理论上它会执行 2 次内存操作,但它可能会缓存在硬件中),但是在 ARM 上,我知道执行未对齐的 32 位访问可能会花费 3 倍就像单个对齐的 32 位加载一样。如果地址未对齐,我想加载对齐选项并获取尽可能多的数据,但不惜一切代价避免另一次内存操作
有没有办法使用神奇的预处理器包含或类似的方法来做到这一点,还是只需要在为平台编译之前手动定义最佳缓存大小?