gpt4 book ai didi

c - __asm__ __volatile__ 的工作 ("": : : "memory")

转载 作者:太空狗 更新时间:2023-10-29 16:19:51 44 4
gpt4 key购买 nike

__asm__ __volatile__ () 的基本作用是什么?对于 ARM 架构,“内存” 的意义是什么?

最佳答案

asm volatile("" ::: "memory");

创建一个编译器级别的内存屏障,强制优化器不对跨越屏障的内存访问进行重新排序。

例如,如果您需要以特定顺序访问某个地址(可能是因为该内存区域实际上由不同的设备而不是内存支持),您需要能够将此告诉编译器,否则它可能只会优化您的步骤是为了提高效率。

假设在这种情况下,您必须递增地址中的一个值,读取一些内容并递增相邻地址中的另一个值。

int c(int *d, int *e) {
int r;
d[0] += 1;
r = e[0];
d[1] += 1;
return r;
}

问题是编译器(gcc 在这种情况下)可以重新安排您的内存访问以获得更好的性能,如果您要求它(-O)。可能导致如下指令序列:

00000000 <c>:
0: 4603 mov r3, r0
2: c805 ldmia r0, {r0, r2}
4: 3001 adds r0, #1
6: 3201 adds r2, #1
8: 6018 str r0, [r3, #0]
a: 6808 ldr r0, [r1, #0]
c: 605a str r2, [r3, #4]
e: 4770 bx lr

同时加载 d[0]d[1] 的上述值。假设这是您想避免的事情,那么您需要告诉编译器不要重新排序内存访问,那就是使用 asm volatile(""::::"memory")

int c(int *d, int *e) {
int r;
d[0] += 1;
r = e[0];
asm volatile("" ::: "memory");
d[1] += 1;
return r;
}

所以你会得到你想要的指令序列:

00000000 <c>:
0: 6802 ldr r2, [r0, #0]
2: 4603 mov r3, r0
4: 3201 adds r2, #1
6: 6002 str r2, [r0, #0]
8: 6808 ldr r0, [r1, #0]
a: 685a ldr r2, [r3, #4]
c: 3201 adds r2, #1
e: 605a str r2, [r3, #4]
10: 4770 bx lr
12: bf00 nop

应该注意的是,这只是编译时内存屏障,以避免编译器重新排序内存访问,因为它没有放置额外的硬件级指令来刷新内存或等待加载或存储完成。如果 CPU 具有架构能力并且内存地址是正常类型而不是强排序设备(ref ).

关于c - __asm__ __volatile__ 的工作 ("": : : "memory"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14950614/

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