【发布时间】:2014-04-21 18:22:18
【问题描述】:
我正在尝试计算 CPUID 指令运行所需的时间。
来源:
#include <stdio.h>
#include <sched.h>
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
static inline unsigned long long tick()
{
unsigned long long d;
asm volatile ("rdtsc" : "=A" (d));
return d;
}
void cpuid(void)
{
int i;
for(i=0; i != 5; i++)
{
asm volatile ("cpuid");
}
}
int main()
{
long long bef;
long long aft;
long long dif;
bef=tick();
cpuid();
aft=tick();
dif=aft-bef;
printf("%d\n", bef);
printf("%d\n", aft);
printF("%d\n", dif);
return 0;
}
现在我正在使用以下代码进行编译
gcc -D_GNU_SOURCE -o test test.c
我在不是文件的代码上遇到错误! 例如:
test.c:6:1: error: expected identifier or '(' before 'do'
test.c:6:1: error: expected identifier or '(' before 'while'
test.c:7:1: error: expected identifier or '(' before '__extension__'
test.c:8:1: warning: data definition has no type or storage class [enable by def...
test.c:8:1: error: intializer element is not constant
“def...”实际上不是输出,因为我的终端窗口很小。我在 ESXi 工作。
任何帮助都会很棒!!!
面向未来的读者
用户@Iwillnotexist Idonotexist 说使用以下函数获得完整的x86 和x64 支持是正确的。
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
【问题讨论】:
-
你将犯同样的错误,太多人在你之前犯过
rdtsc和=Aasm约束...stackoverflow.com/questions/19941588/… -
我理解这一点,但我是否正确地说 RDTSC 返回周期或实际时间并不重要。因为任何一种方式的差异都表明时间已经过去,所以只是您测量的是实际时间还是指定时间内的周期数。我可能是错的。如果我是,你能解释一下吗?
-
问题不在于,问题在于 RDTSC 返回一个 64 位值,但它在寄存器
edx和eax。在 32 位模式下,=A约束正确选择了一对寄存器edx:eax;在 64 位模式下,它不会。相反,您将只阅读rax,其上半部分在rdtsc之后为零。因此,当您减去时,有时您会得到不应该的负值,并且您将无法测量超过几秒钟的时间差,因为您只使用 TSC 计数器的低 32 位. -
如果您将代码更改为在此处使用
#elif defined(__x86_64__)(mcs.anl.gov/~kazutomo/rdtsc.html) 下面的rdtsc()函数版本,而不是您自己的tick(),它将在 32 位和 64 位上工作无处不在的操作系统。 -
我有一个新问题。将此代码移植到 Windows :( 有什么想法吗?
标签: c linux compiler-errors cpu compiler-warnings