gcc,asm volatile的用途是什么(“r”(x))

gcc,asm volatile的用途是什么(“r”(x)),c,gcc,assembly,inline-assembly,volatile,C,Gcc,Assembly,Inline Assembly,Volatile,我在C源代码中看到过以下代码,由gcc在Linux(用于计算机)上编写: extern双倍价格[4000]; void函数() { //每隔5秒再次调用此函数 //一些使用价格的长代码[] // ... int i; 对于(i=0;i

我在C源代码中看到过以下代码,由gcc在Linux(用于计算机)上编写:

extern双倍价格[4000];
void函数()
{
//每隔5秒再次调用此函数
//一些使用价格的长代码[]
// ...
int i;

对于(i=0;i
强制编译在某个寄存器中加载
prices[i]
(对于每次循环执行,都是同一个寄存器,对于执行4000次的循环,仍然使用一个寄存器)

如果只编写了
asm
而没有
volatile
,编译器可以通过删除(或移动)整个语句来优化,然后删除整个循环,因为它什么也不做

试着用

 gcc -O0 -fverbose-asm -S foo.c -o foo-O0.s
 gcc -O1 -fverbose-asm -S foo.c -o foo-O1.s
 gcc -O2 -fverbose-asm -S foo.c -o foo-O2.s
 gcc -O3 -fverbose-asm -S foo.c -o foo-O3.s

查看生成的
foo-O*.s
文件(例如,使用编辑器或类似
less
的寻呼机)是否使用
volatile
关键字volatile关键字告诉编译器不允许移动此程序集块

asm(“:”内存”)
是一个简单的编译器

发件人:

您可以通过写入以下命令来防止asm指令被删除: 关键字volatile在asm之后。[…]volatile关键字指示 该指令具有重要的副作用。GCC不会删除 易失性asm(如果可以访问)


在与编写代码的人讨论后,他说他正在尝试将变量提取到CPU缓存(L1/L2/L3)中

volatile
意味着外部影响可能会改变数据:不要期望每次需要访问时都重新加载数据来保持稳定。实际上,由于没有输出参数,volatile是隐式的。David Wohlferd是正确的。实际上volatile关键字不在问题范围内。我只是想知道代码的作用:asm volatile(“::”r“(价格[i]));Basile Starynkevitch似乎回答了我的一个问题,但是,正如我所说的,CPU中的寄存器数量是有限的,因此由于4000个循环,代码看起来毫无用处,是正确的吗?还是有其他用途?除此之外,@Basile所说的是正确的。除非这段代码有更多内容(引用中的内容?),这是一个无用的浪费时间的循环。如果这是一个面试问题,我可能会外交地推测这是在试图加热缓存。然后我会说这是一个无用的浪费时间的循环。我相信这是我以前推测的。是的,这将把东西读入缓存。这是否比仅仅让它产生任何实际好处g cpu自己管理这一点是有争议的。它更可能做它所做的事情:给以后处理代码的人带来维护问题,以及可移植性问题。@DavidWohlferd使用gcc预取内置而不是这种方法怎么样?你指的是哪种方法?操作系统会自动将内存加载到cpu的缓存中每次您访问它时(例如,当您将值加载到prices数组中时)。它也会在选择时自动将内容从缓存中丢弃。无法“保留”还有,请记住,cpu的缓存是在所有运行的进程之间共享的。因此,虽然您可能认为将这些价格移动到缓存中是一个好主意,但操作系统可以确定某些设备驱动程序信息更有用,并立即将您的所有内容丢弃。因此,我的偏好是(几乎总是)让cpu/OS来处理这个问题。最后一个想法是:在某些非常高性能的例程中进行这种类型的优化是有意义的。如果你想知道这是否真的会在这种情况下产生影响,请使用探查器并对其计时。你甚至可以将其与使用预取进行比较。了解到这一点,我会非常惊讶这里没有任何人类可以感知到的时间被节省下来,而且毫不奇怪地发现它使事情变慢了。
 gcc -O0 -fverbose-asm -S foo.c -o foo-O0.s
 gcc -O1 -fverbose-asm -S foo.c -o foo-O1.s
 gcc -O2 -fverbose-asm -S foo.c -o foo-O2.s
 gcc -O3 -fverbose-asm -S foo.c -o foo-O3.s