返回

优化 Delphi 针对 Android/ARM 目标的代码生成:一份完整指南

Android

改善 Delphi 针对 Android/ARM 目标的代码生成

引言

作为一名 Delphi 开发者,编译代码以在 Android 设备上原生运行的需求十分迫切。虽然 Delphi 编译器利用 LLVM 后端为 ARM 设备生成代码,但默认情况下生成的代码效率并不尽如人意。本指南将深入探讨如何优化 Delphi 代码生成,从而生成更紧凑且高效的 ARM 代码。

问题的根源

Delphi 在处理 ARM 目标时存在一些编译器行为,阻碍了代码的优化。这些问题包括:

  • 大量使用堆栈
  • 仅将寄存器 r0-r3 用作临时变量
  • 以 4 个字节对字节加载操作加载普通 32 位整数

解决方法

为了解决这些问题,我们可以采取以下步骤:

  • 减少堆栈使用: 通过使用全局变量或寄存器分配策略来存储局部变量,从而减少堆栈使用。
  • 优化寄存器使用: Delphi 倾向于将寄存器 r0-r3 用作临时变量,这限制了编译器的优化能力。通过在代码中使用更多的寄存器并明确管理寄存器分配,可以提高代码效率。
  • 优化加载操作: Delphi 将 32 位整数加载为 4 个字节对字节加载操作,这会浪费指令。通过使用编译器选项或手动内联汇编来优化这些加载操作,可以显著提高性能。

编译器选项

Delphi 提供了一些编译器选项,可影响生成的 ARM 代码的优化级别。这些选项包括:

  • 优化(-O): 启用代码优化。
  • 编译至寄存器(-r): 强制编译器将局部变量分配到寄存器。
  • 汇编内存(-a): 生成汇编内存优化,可以减少加载操作的数量。

手动汇编内联

对于更精细的优化,可以使用手动汇编内联来修改 Delphi 生成的代码。通过在代码中使用 inline asm 指令,可以访问 LLVM 的底层优化功能,并手动调整加载操作、寄存器分配和其他代码生成细节。

示例优化

以下是针对 Android/ARM 目标优化代码的一个示例:

// 原代码
function ReadInteger(APInteger : PInteger) : Integer;
begin
  Result := APInteger^;
end;

// 优化代码
inline asm
mov r0, [APInteger]
ldmia r0, {r0, r1}
and r0, r0, r1, lsr #8
and r1, r1, r0, lsl #8
orr r0, r0, r1, lsl #16
mov Result, r0
end;

结论

通过了解 Delphi 编译器针对 Android/ARM 目标的代码生成行为,以及采取适当的优化措施,可以显著提高生成代码的效率。减少堆栈使用、优化寄存器使用以及调整加载操作,可以生成更紧凑、更快速的代码,从而提升 Android 应用程序的性能。

常见问题解答

1. 为什么 Delphi 默认情况下不生成更优化的代码?

Delphi 编译器优先考虑代码的可移植性,而不是特定平台的优化。

2. 是否有工具可以帮助我优化 Delphi 代码?

是的,有一些第三方工具可以分析和优化 Delphi 代码,例如 Embarcadero Prism 和 Pascal Inspector。

3. 优化代码生成是否会影响代码的维护性?

过度优化可能会使代码难以阅读和维护。建议在优化和代码可维护性之间取得平衡。

4. 如何针对其他 ARM 架构优化代码?

Delphi 支持多种 ARM 架构,例如 ARMv6、ARMv7 和 ARM64。针对特定架构进行优化需要了解该架构的特定功能和限制。

5. 还有哪些其他方法可以提高 Android 应用程序的性能?

除了优化 Delphi 代码生成外,还可以通过使用优化的算法、减少内存分配以及避免耗时的操作来提高 Android 应用程序的性能。