[英]inline asm code organization
我剛剛編寫了一些小的內聯asm例程來查詢x86中的時間戳計數器,以便可以分析一小段代碼。 我真的很想將這些例程放在標頭中,以便可以在許多不同的源文件中重用它們,所以基本上我的問題是我應該只在宏中組織它們還是使它們成為內聯函數,我對內聯的懷疑是它不是必然是編譯器實際上會內聯它的情況,並且由於它是對性能敏感的調用,所以我寧願跳過函數調用的開銷,另一方面,使用宏,整個類型的安全性都會消失,為此我將嚴格需要32位int ,我認為我可以只在注釋中添加規范,但由於許多警告,我仍然盡量避免使用宏。 這是代碼:
inline void rdtsc(uint64_t* cycles)
{
uint32_t cycles_high, cycles_low;
asm volatile (
".att_syntax\n"
"CPUID\n\t" //Serialize
"RDTSC\n\t" //Read clock and cpuid
"mov %%edx, %0 \n\t"
"mov %%eax, %1 \n\t"
: "=r" (cycles_high), "=r" (cycles_low)
:: "%edx", "%eax");
*cycles = ((uint64_t) cycles_high << 32) | cycles_low;
}
歡迎對此提出任何建議。 我只是想弄清楚這種情況下首選的樣式。
由於您將要測量部分代碼的性能,而不必測量整個函數的性能,因此您不應嘗試內聯性能計數器。 是否有通話開銷都沒有關系。 重要的是,測量結果是一致的,這意味着您要么總是希望存在呼叫開銷,要么永遠不要。 第一個比前一個更容易實現。
讓您的代碼的每個部分都具有相同的調用開銷。
如果您真的需要在讀取TSC之前進行序列化,則可以使用LFENCE指令,該指令不會更改寄存器。
如果決定繼續使用CPUID進行序列化,則應首先將EAX設置為0(可能是0,因為您實際上並不關心輸出),並注意此指令會破壞EAX,EBX,ECX和EDX寄存器,因此您的例行程序必須說明這個事實。
總之,我傾向於這樣寫:
#include <stdint.h>
#include <stdio.h>
inline uint64_t rdtsc() {
uint32_t high, low;
asm volatile (
".att_syntax\n\t"
"LFENCE\n\t"
"RDTSC\n\t"
"movl %%eax, %0\n\t"
"movl %%edx, %1\n\t"
: "=rm" (low), "=rm" (high)
:: "%edx", "%eax");
return ((uint64_t) high << 32) | low;
}
int main() {
uint64_t x, y;
x = rdtsc();
printf("%lu\n", x);
y = rdtsc();
printf("%lu\n", y);
printf("%lu\n", y-x);
}
@Jester和@DavidWohlferd提出,可以通過直接將high
和low
分配給edx
和eax
寄存器來消除寄存器分配。
該版本如下所示:
inline uint64_t rdtsc() {
uint32_t high, low;
asm volatile (
".att_syntax\n\t"
"LFENCE\n\t"
"RDTSC\n\t"
: "=a" (low), "=d" (high)
:: );
return ((uint64_t) high << 32) | low;
}
生成的代碼(使用運行-O2的優化)(在運行Linux的64位計算機上使用gcc 4.8.3)並包括對printf
的調用,如下所示:
#APP
# 20 "rdtsc.c" 1
.att_syntax
LFENCE
RDTSC
# 0 "" 2
#NO_APP
movq %rdx, %rbx
movl %eax, %eax
movl $.LC0, %edi
salq $32, %rbx
orq %rax, %rbx
xorl %eax, %eax
movq %rbx, %rsi
call printf
我最初發布的版本結果如下:
#APP
# 7 "rdtsc.c" 1
.att_syntax
LFENCE
RDTSC
movl %eax, %ecx
movl %edx, %ebx
# 0 "" 2
#NO_APP
movl %ecx, %ecx
salq $32, %rbx
movl $.LC0, %edi
orq %rcx, %rbx
xorl %eax, %eax
movq %rbx, %rsi
call printf
該版本的代碼長了一條指令。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.