【发布时间】:2019-11-16 06:35:30
【问题描述】:
我正在处理一个具有重大 RAM 限制的遗留 Ada 项目。
为了为附加功能节省内存,我想分析所有记录定义,以便:
- 检测漏洞(即浪费的字节)
- 提出最小化内存占用的记录声明顺序(或表示)(使用一些应该类似于Knapsack problem 的算法)
请注意,我还没有(还)在保存任何丢失的 位(这里不需要 pragma pack,也不需要像 @ 中的严格连续记录的 rep. 子句987654322@)。目前只有字节。
简化示例(真实世界记录要复杂得多,可能有判别式、标记类型):
type My_Record is record
field1 : Foo; -- enum with 3 values
field2 : Bar; -- some other record
field3 : Float; -- 32 bits
field4 : Flex;-- enum with 12 values
end record;
它的-gnatR2s 输出看起来像(32 位世界):
for My_Record'Alignment use 4;
for My_Record use record
field1 at 0 use 0.. 7;
field2 at 4 use 0..47; -- 3 bytes lost from field 1
field3 at 12 use 0..31; -- 2 bytes lost from field 2
field4 at 16 use 0.. 7; -- another 3 bytes lost
end record;
我想做的事(内存使用优化记录):
-- rewrite record, not the preferred way since record writing order may have some human readable context purpose
type My_Record is record
field2 : Bar; -- 2 unused bytes
field1 : Foo; -- 1 byte left
field4 : Flex; -- 0 byte left
field3 : Float; -- 4 bytes used
-- 0 wasted bytes
end record;
或:
-- preferred way : keep record declaration, but force rep. clause
type My_Record is record
field1 : Foo;
field2 : Bar;
field3 : Float;
field4 : Flex;
end record;
-- optimization is here
for My_Record'alignment use 4;
for My_Record use record
field2 at 0 use 0..47;
field1 at 6 use 0.. 7; -- exploit the Bar unused bytes
field4 at 7 use 0.. 7; -- exploit the Bar unused bytes
field3 at 8 use 0..31;
end record;
(对于示例中的任何错误,我深表歉意,希望您明白这一点)
我该怎么做?
- ASIS(但我的技能为 0%,我什至不确定它是否能做我想做的事)
- libadalang(如何在不编译单元的情况下获得代表子句?)
- 只需在所有编译单元上使用
-gnatR2s并在python 中编写.rep解析器 - 有一个隐藏的编译选项、编译指示或现有的 GNAT 工具可以提供帮助(例如 pragma component_alignment 或 pragma optimize_alignment,但我不能说他们是否解决了这个问题,因为它会影响 对齐,但不一定对齐+排序)
关于 repl 子句的上下文,Ada 参考手册和 GNAT 的细微差别,可以阅读this link
【问题讨论】:
标签: record ada representation ada2012