在C语言中设置CPU相关性时遇到的问题
我正在尝试计算CPUID指令运行所需的时间 资料来源:在C语言中设置CPU相关性时遇到的问题,c,linux,compiler-errors,cpu,compiler-warnings,C,Linux,Compiler Errors,Cpu,Compiler Warnings,我正在尝试计算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 lo
#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;
}
我在不是文件的代码上出错!
例如:
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
定义。。。实际上输出不是因为我的终端窗口很小。我在ESXi工作
任何帮助都将是惊人的
给未来的读者
User@Iwillnotexist idotnotexist正确地说,使用以下函数可以获得完整的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 );
}
你有一个函数之外的代码。这是不允许的。将以下内容移到主菜单中:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
你有一个函数之外的代码。这是不允许的。将以下内容移到主菜单中:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
这些说明应包含在主目录中:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
这将修复编译错误
然后,cpuid的五次迭代太少,无法给出有意义的结果
您可以检查这一点,但只使用CPUID指令生成的两个不同长度的序列。你需要一个更长的周期,但不要太长,让内存进入游戏
我已经运行了一些测试,测试定义在5到1000之间;CPU亲和力似乎不会影响四核上的结果:
#include <stdio.h>
#include <sched.h>
static inline unsigned long long tick() {
unsigned long long d;
asm volatile ("rdtsc" : "=A" (d));
return d;
}
static inline void cpuid(void) {
int i;
for(i=0; i != TEST; i++) {
asm volatile ("cpuid");
}
}
int main()
{
long long bef, aft, dif;
bef=tick();
cpuid();
aft=tick();
dif=(aft-bef)/TEST;
printf("%lld\n", dif);
return 0;
}
gcc -o0 -DTEST=100 -D_GNU_SOURCE -W -Wall -o time time.c && ./time
这些说明应包含在主目录中:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
这将修复编译错误
然后,cpuid的五次迭代太少,无法给出有意义的结果
您可以检查这一点,但只使用CPUID指令生成的两个不同长度的序列。你需要一个更长的周期,但不要太长,让内存进入游戏
我已经运行了一些测试,测试定义在5到1000之间;CPU亲和力似乎不会影响四核上的结果:
#include <stdio.h>
#include <sched.h>
static inline unsigned long long tick() {
unsigned long long d;
asm volatile ("rdtsc" : "=A" (d));
return d;
}
static inline void cpuid(void) {
int i;
for(i=0; i != TEST; i++) {
asm volatile ("cpuid");
}
}
int main()
{
long long bef, aft, dif;
bef=tick();
cpuid();
aft=tick();
dif=(aft-bef)/TEST;
printf("%lld\n", dif);
return 0;
}
gcc -o0 -DTEST=100 -D_GNU_SOURCE -W -Wall -o time time.c && ./time
使用rdtsc和=A asm约束,您将犯下许多其他人在您之前犯过的相同错误。。。我明白这一点,但我说的对吗?RDTSC返回周期或实际时间都无关紧要。因为任何一种方式的差异都表明时间已经过去,所以它只是以实际时间或指定时间内的循环量进行测量。我可能错了。如果我是,你能解释一下吗?问题不在于此,问题在于RDTSC返回一个64位的值,但它在寄存器edx和eax中被分成hi和lo两半。在32位模式下,=A约束正确选择一对寄存器edx:eax;在64位模式下,它不会。相反,您将只阅读rax,其上半部分在rdtsc后为零。因此,当你进行减法运算时,有时你会在不应该的情况下得到负值,并且你无法测量超过几秒钟的时间差,因为你只使用TSC计数器的低位32位。如果你将代码更改为使用下面的rdtsc函数版本,而不是你自己的勾号,它可以在任何地方的32位和64位操作系统上运行。我有一个新问题。将此代码移植到windows:有什么想法吗?您将犯下许多其他人在使用rdtsc和=A asm约束之前犯过的相同错误。。。我明白这一点,但我说的对吗?RDTSC返回周期或实际时间都无关紧要。因为任何一种方式的差异都表明时间已经过去,所以它只是以实际时间或指定时间内的循环量进行测量。我可能错了。如果我是,你能解释一下吗?问题不在于此,问题在于RDTSC返回一个64位的值,但它在寄存器edx和eax中被分成hi和lo两半。在32位模式下,=A约束正确选择一对寄存器edx:eax;在64位模式下,它不会。相反,您将只阅读rax,其上半部分在rdtsc后为零。因此,当你进行减法运算时,有时你会在不应该的情况下得到负值,并且你无法测量超过几秒钟的时间差,因为你只使用TSC计数器的低位32位。如果你将代码更改为使用下面的rdtsc函数版本,而不是你自己的勾号,它可以在任何地方的32位和64位操作系统上运行。我有一个新问题。将这段代码移植到windows:有什么想法吗?好的,那么将亲和性的东西转移到主要作品中。我想做的是测量执行CPUID所需的时间。因为这是一条离开虚拟环境的指令。因此,我希望在VM中执行指令的时间会增加。我希望它们会是激烈的,因为我的研究旨在从VM中的可执行文件中识别虚拟环境。我还看到RDTSC在不一致的基础上返回负值!这就是为什么我决定设置CPU亲和力,以防指令通过内核,如果这样的话。我看到的dif大约为80000。这是否很大?@user3078629您是否看到我在w.r.t.上面的评论。在asm volatile rdtsc:=A d;为什么这是错误的?你一定要改变这一点。例如,这里的x86_64解决方案
这是一种方法。好吧,把亲和性的东西移到主要作品中。我想做的是测量执行CPUID所需的时间。因为这是一条离开虚拟环境的指令。因此,我希望在VM中执行指令的时间会增加。我希望它们会是激烈的,因为我的研究旨在从VM中的可执行文件中识别虚拟环境。我还看到RDTSC在不一致的基础上返回负值!这就是为什么我决定设置CPU亲和力,以防指令通过内核,如果这样的话。我看到的dif大约为80000。这是否很大?@user3078629您是否看到我在w.r.t.上面的评论。在asm volatile rdtsc:=A d;为什么这是错误的?你一定要改变这一点。例如,这里的x86_64解决方案是一种方法。