在英特尔手册的RDTSC指令警告说,当实际执行RDTSC乱序执行可以改变,所以他们建议将在它前面的CPUID指令,因为CPUID将序列指令流(CPUID是永远不会乱序执行).我的问题很简单:如果他们有能力进行序列化指令,他们为什么不进行RDTSC序列化?它的全部要点似乎是获得周期精确的时间.是否存在一种情况,您不希望在它之前加上序列化指令?
较新的Intel CPU具有单独的序列化RDTSCP指令.英特尔选择引入一个单独的指令,而不是改变RDTSC的行为,这表明我必须存在一些可能出现故障时序的情况.它是什么?
我试图找到大约每个操作需要多少CPU周期的参考.
我不需要确切的数字(因为这会在CPU之间有所不同),但我想要一些相对可信的东西,这可以提供我可以引用与朋友讨论的数据.
作为一个例子,我们都知道浮点除法比做位移更多的CPU周期.
我猜不同之处在于,除法是大约100个周期,其中一个班次是1,但我正在寻找一些东西来引导它.
任何人都可以推荐这样的资源?
来自该SO螺纹,这块代码计算的CPU周期的数目经过延伸的线之间的代码//1和//2.
$ cat cyc.c
#include<stdio.h>
static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
int main() {
unsigned long long cycles = rdtsc(); //1
cycles = rdtsc() - cycles; //2
printf("Time is %d\n", (unsigned)cycles);
return 0;
}
$ gcc cyc.c -o cyc
$ ./cyc
Time is 73
$ ./cyc
Time is 74
$ ./cyc
Time is 63
$ ./cyc
Time …Run Code Online (Sandbox Code Playgroud) 在Computer Systems:A Programmer's Perspective一书中,练习5.5显示了一段代码来计算多项式的值
double poly(double a[], double x, int degree)
{
long int i;
double result = a[0];
double xpwr = x;
for (i = 1; i <= degree; i++) {
result += a[i] * xpwr;
xpwr = x * xpwr;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
练习假设双精度浮点加法和乘法所需的时钟周期分别为3和5.要求读者解释为什么测量的CPE(每元素周期数)值为5.
按照习题答案,在每次迭代中,我们需要更新变量xpwr和result我们需要的,操作是一个浮点加法(对于result)和浮点乘法(对于xpwr),因此后者占主导地位的延迟,导致最终CPE为5.
但我认为数据流应该是这样的:
xpwr result
| |
+-----+ +--[load] |
| | | |
[mul] [mul] |
| | |
| +---+ +-----+ …Run Code Online (Sandbox Code Playgroud) 在Win32中,有没有办法获得一个独特的cpu循环计数或类似的东西,对于多个进程/语言/系统/等是统一的.
我正在创建一些日志文件,但是必须生成多个日志文件,因为我们正在托管.NET运行时,并且我想避免从一个调用到另一个来进行日志记录.因此,我认为我只生成两个文件,将它们组合在一起,然后对它们进行排序,以获得涉及跨世界调用的连贯时间线.
但是,每次通话都不会增加GetTickCount,因此不可靠.是否有更好的号码,以便在排序时以正确的顺序接听电话?
编辑:感谢@Greg把我带到QueryPerformanceCounter的轨道,这就是诀窍.
CPU周期(或者,实质上,"速度")之间有什么不同
x /= y;
Run Code Online (Sandbox Code Playgroud)
和
#include <cmath>
x = sqrt(y);
Run Code Online (Sandbox Code Playgroud)
编辑:我知道操作不等同,我只是随意提出x /= y作为基准x = sqrt(y)
我打算在接下来的几个月里创建一个Sega Master System模拟器,作为Java中的一个爱好项目(我知道它不是最好的语言,但我发现它很舒服,并且作为一个频繁的用户Windows和Linux我认为跨平台应用程序会很棒).我的问题是关于循环计数;
我查看了另一个Z80模拟器的源代码,以及其他模拟器,特别是执行循环引起了我的兴趣 - 当它被调用时,一个int作为参数传递(假设以1000为例).现在我得到每个操作码执行不同的循环次数,并且当执行这些循环时,循环次数从总体数字减少.一旦剩余的周期数<= 0,执行循环就完成了.
我的问题是,这些仿真器中的许多都没有考虑到这样一个事实,即要执行的最后一条指令可以将周期数推到负值 - 这意味着在执行循环之间,最终可能会说1002个周期执行而不是1000.这是重要的吗?一些仿真器通过补偿下一个执行循环来解决这个问题,有些则不能 - 哪种方法最好?请允许我说明一下我的问题,因为我并不擅长将自己放在一边:
public void execute(int numOfCycles)
{ //this is an execution loop method, called with 1000.
while (numOfCycles > 0)
{
instruction = readInstruction();
switch (instruction)
{
case 0x40: dowhatever, then decrement numOfCycles by 5;
break;
//lets say for arguments sake this case is executed when numOfCycles is 3.
}
}
Run Code Online (Sandbox Code Playgroud)
在此特定循环示例结束后,numOfCycles将为-2.这只会是一个小小的不准确,但在人们的经历中总体上是否重要?我很欣赏任何人对这一点的见解.我计划在每帧之后中断CPU,因为这似乎合适,所以1000个周期很低我知道,这只是一个例子.
非常感谢,菲尔
真实的CPU频率和C语言中的clock_t(单位是时钟节拍)之间有什么关系?
假设我有下面一段 C 代码,它测量 CPU 运行循环所消耗的时间for。
但由于 CLOCKS_PER_SEC 在 C 标准库中是一个常量值(基本上是 1000,000),我想知道该clock函数如何测量程序在具有不同 CPU 频率的不同计算机上运行时所消耗的实际 CPU 周期(对于我来说)笔记本电脑,它是 2.6GHz)。
如果它们不相关,CPU 计时器在上述场景中如何工作?
#include <time.h>
#include <stdio.h>
int main(void) {
clock_t start_time = clock();
for(int i = 0; i < 10000; i++) {}
clock_t end_time = clock();
printf("%fs\n", (double)(end_time - start_time) / CLOCKS_PER_SEC);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个RHEL盒子,我需要在适度和可变的CPU负载量(50%-75%)下放置.
最好的方法是什么?是否有一个程序可以做到这一点,我不知道?我很乐意编写一些C代码来实现这一点,我只是不知道系统调用会有什么帮助.
我用C编写了一个程序.它是一个由研究创建的程序.我想计算程序消耗的精确CPU周期.确切的周期数.知道我怎么能找到它?