gpt4 book ai didi

c - 如果只有一次迭代,gcc 优化会删除 for 循环吗?

转载 作者:行者123 更新时间:2023-12-03 23:58:06 25 4
gpt4 key购买 nike

我正在编写一个实时 DSP 处理库。我的目的是赋予它定义输入样本 block 大小的灵 active ,同时在逐个样本处理的情况下也具有最佳性能,即 - 单个样本 block 大小

我认为我必须使用 volatile 关键字定义循环变量,因为数据处理将使用指向输入/输出的指针。

这引出了一个问题:

gcc 编译器会优化这段代码

int blockSize = 1;
for (volatile int i=0; i<blockSize; i++)
{
foo()
}

//.h
#define BLOCKSIZE 1

//.c
for (volatile int i=0; i<BLOCKSIZE; i++)
{
foo()
}

与简单地调用循环体相同:

foo()

?

谢谢

最佳答案

I think I have to use volatile keyword defining loop variable since data processing will be using pointers to Inputs/Outputs.

不,这没有任何意义。只有输入/输出硬件寄存器本身应该是volatile。指向它们的指针应声明为指向volatile 数据的指针,即volatile uint8_t*。不需要让指针本身volatile,即uint8_t* volatile//wrong

就目前的情况而言,您强制编译器创建一个变量 i 并增加它,这可能会阻止循环展开优化。

使用 -O3 在 gcc x86 上尝试您的代码,这正是发生的情况。无论BLOCKSIZE的大小,它仍然会因为volatile而产生循环。如果我删除 volatile 它会完全展开循环到 BLOCKSIZE == 7 并用许多函数调用替换它。超过 8 会创建一个循环(但将迭代器保存在寄存器中而不是 RAM 中)。

x86 示例:

for (int i=0; i<5; i++)
{
foo();
}

给予

    call    foo
call foo
call foo
call foo
call foo

但是

for (volatile int i=0; i<5; i++)
{
foo();
}

效率低下

        mov     DWORD PTR [rsp+12], 0
mov eax, DWORD PTR [rsp+12]
cmp eax, 4
jg .L2
.L3:
call foo
mov eax, DWORD PTR [rsp+12]
add eax, 1
mov DWORD PTR [rsp+12], eax
mov eax, DWORD PTR [rsp+12]
cmp eax, 4
jle .L3
.L2:

进一步研究volatile在嵌入式系统中的正确使用,请看:

关于c - 如果只有一次迭代,gcc 优化会删除 for 循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67500274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com