gpt4 book ai didi

c - __asm__ __volatile__ 在 C 中做什么?

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

我研究了一些来自
的C代码 http://www.mcs.anl.gov/~kazutomo/rdtsc.html
他们使用诸如 __inline____asm__ 等东西,如下所示:

代码1:

static __inline__ tick gettick (void) {
unsigned a, d;
__asm__ __volatile__("rdtsc": "=a" (a), "=d" (d) );
return (((tick)a) | (((tick)d) << 32));
}

代码2:

volatile int  __attribute__((noinline)) foo2 (int a0, int a1) {
__asm__ __volatile__ ("");
}

我想知道 code1 和 code2 的作用是什么?

(编者注:对于这个特定的 RDTSC 用例,内在函数是首选:How to get the CPU cycle count in x86_64 from C++? 另请参见 https://gcc.gnu.org/wiki/DontUseInlineAsm)

最佳答案

__asm__ block 上的 __volatile__ 修饰符强制编译器的优化器按原样执行代码。如果没有它,优化器可能会认为它可以完全删除,或者从循环中提取并缓存。

这对 rdtsc 指令很有用,如下所示:

__asm__ __volatile__("rdtsc": "=a" (a), "=d" (d) )

这不需要任何依赖关系,因此编译器可能会假设该值可以被缓存。 Volatile 用于强制它读取新的时间戳。

单独使用时,像这样:

__asm__ __volatile__ ("")

它实际上不会执行任何操作。不过,您可以扩展它,以获得不允许对任何内存访问指令重新排序的编译时内存屏障:

__asm__ __volatile__ ("":::"memory")

rdtsc 指令是 volatile 的一个很好的例子。 rdtsc 通常在需要计算某些指令的执行时间时使用。想象一下这样的代码,您想要在其中计时 r1r2 的执行:

__asm__ ("rdtsc": "=a" (a0), "=d" (d0) )
r1 = x1 + y1;
__asm__ ("rdtsc": "=a" (a1), "=d" (d1) )
r2 = x2 + y2;
__asm__ ("rdtsc": "=a" (a2), "=d" (d2) )

这里实际上允许编译器缓存时间戳,并且有效的输出可能显示每行恰好花费了 0 个时钟来执行。显然这不是你想要的,所以你引入 __volatile__ 来防止缓存:

__asm__ __volatile__("rdtsc": "=a" (a0), "=d" (d0))
r1 = x1 + y1;
__asm__ __volatile__("rdtsc": "=a" (a1), "=d" (d1))
r2 = x2 + y2;
__asm__ __volatile__("rdtsc": "=a" (a2), "=d" (d2))

现在你每次都会得到一个新的时间戳,但它仍然有一个问题,即允许编译器和 CPU 重新排序所有这些语句。它可能会在 r1 和 r2 已经计算出来之后执行 asm block 。要解决此问题,您需要添加一些强制序列化的障碍:

__asm__ __volatile__("mfence;rdtsc": "=a" (a0), "=d" (d0) :: "memory")
r1 = x1 + y1;
__asm__ __volatile__("mfence;rdtsc": "=a" (a1), "=d" (d1) :: "memory")
r2 = x2 + y2;
__asm__ __volatile__("mfence;rdtsc": "=a" (a2), "=d" (d2) :: "memory")

请注意此处的 mfence 指令,它强制执行 CPU 端屏障,而 volatile block 中的“内存”说明符强制执行编译时屏障。在现代 CPU 上,您可以将 mfence:rdtsc 替换为 rdtscp 以提高效率。

关于c - __asm__ __volatile__ 在 C 中做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26456510/

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