我正在使用 ARM7TDMI 处理器开发嵌入式系统。
在时间紧迫的 ISR 中,我需要将 24 个 16 位值从硬件寄存器快照(复制)到 SRAM 中。这些值是连续的,可以视为一个数组。
数据总线(到 SRAM 和硬件寄存器)是 16 位的,我们在 ARM 模式下运行(8/32)。
在商店中,我们正在讨论复制数据的最佳方法:作为 16 位数量或作为 32 位数量。
我的论点是 ARM 处于 32 位模式,因此使用一条指令进行 2 次 16 位取指比使用两条 16 位指令每次取指一次要快。
此外,要获取的指令数量是原来的一半,这应该会减少 1/2 的时间。
有人有任何数据支持这两种方法吗? (我的 O'scopes 都已分配,所以我无法在嵌入式系统上进行测量。由于 ISR 每毫秒中断一次,也无法运行大量时间。) *(分析很困难,因为我们的 JTAG Jet 探头没有'不提供准确分析的方法)。*
示例代码 - 16 它复制:
#define MAX_16_BIT_VALUES 24U
uint16_t volatile * p_hardware;
uint16_t data_from_hardware[MAX_16_BIT_VALUES];
data_from_hardware[0] = p_hardware[0];
data_from_hardware[1] = p_hardware[1];
data_from_hardware[2] = p_hardware[2];
data_from_hardware[3] = p_hardware[3];
//...
data_from_hardware[20] = p_hardware[20];
data_from_hardware[21] = p_hardware[21];
data_from_hardware[22] = p_hardware[22];
data_from_hardware[23] = p_hardware[23];
示例代码,32 位副本:
uint32_t * p_data_from_hardware = (uint32_t *)&data_from_hardware[0];
uint32_t volatile * p_hardware_32_ptr = (uint32_t volatile *) p_hardware;
p_data_from_hardware[0] = p_hardware_32_ptr[0];
p_data_from_hardware[1] = p_hardware_32_ptr[1];
p_data_from_hardware[2] = p_hardware_32_ptr[2];
p_data_from_hardware[3] = p_hardware_32_ptr[3];
//...
p_data_from_hardware[ 8] = p_hardware_32_ptr[ 8];
p_data_from_hardware[ 9] = p_hardware_32_ptr[ 9];
p_data_from_hardware[10] = p_hardware_32_ptr[10];
p_data_from_hardware[11] = p_hardware_32_ptr[11];
详细信息:ARM7TDMI 处理器以 8/32 位模式运行,IAR EW 编译器。
注意:展开代码是为了防止指令缓存重新加载。
注意:汇编语言列表显示使用常量索引访问内存比使用递增指针更有效。
编辑 1:测试
根据 Chris Stratton 的评论,我们在 16 位 FPGA 寄存器上进行 32 位获取时遇到问题,因此无法进行 32 位优化。
也就是说,我使用 DMA 进行了分析。使用 DMA 控制器的性能提升为 30 us(微秒)。在我们的项目中,我们希望节省更多的时间,所以这种优化是不值得的。这个实验表明,如果我们有更多的数据要传输,DMA 将非常有用,或者传输可以是并行的。
有趣的是,DMA 需要 17 条指令来设置。