目标是调用 WaitReps(x)(其中 x>0)并让线程重复执行 x 次“pause/dec ecx”。调用者是一个固定线程。代码:
class WaitUtil {
public:
static void WaitReps(u_int64_t count);
};
inline
void WaitUtil::WaitReps(u_int64_t count) {
// repeat until ecx 0
asm volatile (
".rep \n\t"
"pause \n\t"
"dec ecx \n\t"
".endr \n\t"
:
: "c" (count)
);
}
该文件是使用 g++ -O3 -march=native ... 和 LTO 编译的。 该死的...无论我做什么,可执行文件中都缺少代码。编译 -O0 没有帮助。禁用 LTO 也不会。
objdump -d
任务上没有显示暂停指令。
我认为
volatile
应该告诉 g++/gasm 放手。我还尝试将函数放入 .cpp 文件中并删除内联。
我可以通过检查临时文件(-save-temps)来确认,g++ 使代码was在那里,直到有东西将其剥离。这是来自 .s 文件中计数为 4000000 的任务的调用:
movl $4000000, %ecx
movq %rax, %rdi
salq $32, %rdx
orq %rdx, %rdi
#APP
# 22 "syncthread_waitutil.h" 1
.rep
pause
dec ecx
.endr
如何让编译发出指定的代码?
谢谢你
奖励:如果我能弄清楚如何将常量传递给 .rept,则可以避免传递重复计数和递减 ecx。但这很好,只有:
asm volatile (
".rept %[cnt] \n\t"
"pause \n\t"
".endr \n\t"
:
: "cnt" "r" (count)
);
您可以使用
i
约束来强制立即数,并使用 c
修饰符以 .rept
工作的方式打印它:
asm volatile (
".rept %c0\n\t"
"pause\n\t
".endr"
:: "i"(cnt));`
这仅在优化编译时有效。 如果没有优化,它就无法编译。