c - 在 C 中,ARM 编译器将如何优化此结构?

标签 c optimization compiler-construction arm

我有一个结构:

typedef struct mystruct_s {
    uint8_t bufferA[1024];
    uint8_t bufferB[1024];
} mystruct;

mystruct mystructA;
mystruct mystructB;

for( i = 0 ; i < 1024 ; i++ )
{
    mystructA.bufferA[i] = 0x01;
    mystructA.bufferB[i] = 0x01;
    mystructB.bufferA[i] = 0x01;
}

在我的程序中,我访问了 mystructA 中的两个缓冲区成员,但只访问了 mystructB 中的缓冲区 A。

如果不访问 mystructB 中的成员 bufferB,编译器会优化它以节省内存吗?

我知道由于不同编译器的性质,这可能看起来模棱两可。

例如,如果我在 Keil 下为 STM32F4 使用 ARM C/C++ 编译器,它会做什么?

最佳答案

If member bufferB in mystructB is not accessed will the compiler optimize it out to save memory?

不,不允许编译器更改结构的内存布局。您已经告诉它保留 1024 个字节,因此它必须这样做。它不能“部分优化”一个结构:它要么优化掉整个结构分配,要么什么也不做。

这不是模棱两可或依赖于系统的,所有标准编译器都必须这样做。但是,mystructB.bufferB 将包含垃圾值。


与优化相关:

一般来说,从同一个循环中的多个位置“触摸”RAM 内存并不是一个好主意。在循环的每一圈,您都会阅读 3 个不相邻的不同区域。这可能会阻止 CPU 有效地使用数据缓存,迫使它在循环的每一圈直接写入 RAM。

即使启用了所有优化,编译器通常也不会考虑数据缓存,因为缓存内存的性质是系统特定的。

根据 MCU 数据缓存的工作方式,您实际上可以通过创建更多循环来显着提高性能:

for( i = 0 ; i < 1024 ; i++ )
    mystructA.bufferA[i] = 0x01;
for( i = 0 ; i < 1024 ; i++ )
    mystructA.bufferB[i] = 0x01;
for( i = 0 ; i < 1024 ; i++ )
    mystructB.bufferA[i] = 0x01;

现在数据以线性顺序访问,这将导致最佳缓存使用。循环的顺序很重要,它应该与分配的顺序相同。

或者,使用 memset(),因为您正在处理字节。

关于c - 在 C 中,ARM 编译器将如何优化此结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45631662/

相关文章:

java - 将 void 算法转换为 int []

php - 如何优化这个网站。需要一般建议

compiler-construction - 编译 Debug模式时出错 : C++/CLI - error LNK2022

multithreading - 使用多核提高并行性能

cocoa - 综合属性和 ivar 错误

c - 如何在非常慢的应用程序中查找内存泄漏?

C - malloc 或 fgets,我不知道什么不起作用

c - 如何更改链表以便删除最后一个链接并替换第一个链接?

python - 如何进一步优化这个python脚本?

c++ - 创建操作系统关闭按钮? (WinAPI)