我正在编写一个程序来确定每秒可以运行多少nop,但是我得到的数字似乎非常小。
int main()
{
struct timeval tvStart, tvDiff, tvEnd;
unsigned int i;
unsigned long numberOfRuns = 0xffffffff;
gettimeofday(&tvStart, NULL);
for(i = 0; i < (unsigned int) 0xffffffff; i++)
{
hundred(); /*Simple assembly loop that runs 100 times and returns */
}
gettimeofday(&tvEnd, NULL);
timeval_subtract(&tvDiff, &tvEnd, &tvStart);
/* Get difference in time in microseconds */
unsigned long nopTime = (tvDiff.tv_sec * 1000000L) + tvDiff.tv_usec;
printf("NOP Seconds: %lun", nopTime);
gettimeofday(&tvStart, NULL);
for(i = 0; i < (unsigned int) 0xffffffff; i++)
{
none(); /* Assembly function that just returns */
}
gettimeofday(&tvEnd, NULL);
timeval_subtract(&tvDiff, &tvEnd, &tvStart);
/* Get difference in time in microseconds */
unsigned long retTime = (tvDiff.tv_sec * 1000000L) + tvDiff.tv_usec;
printf("RET Seconds: %lun", retTime);
unsigned long avgTime = nopTime - retTime;
/* Takes number of NOP runs and divides it by the time taken
and multiplies by 1,000,000 to convert to seconds */
printf("%lun", ((numberOfRuns * 100) / avgTime) * 1000000);
}
我做的第一件事是运行一个由100条NOP指令0xffffffff
组成的汇编循环,并将其花费的时间存储在nopTime
中。然后,我做同样的事情,但是调用一个只返回。
我相信我每秒至少应该得到10亿条NOP指令,如果不是更多的话,但我甚至没有接近。下面是我最后一次运行的输出:
NOP Seconds: 251077086
RET Seconds: 10450449
/* Calculated number of NOPs per second */
17000000
我不太习惯使用更大的数据类型,所以东西被截断了,我没有意识到吗?我应该使用双打吗?似乎当我摆弄数据类型时,我得到了不同的数字,但它们也是相当小的数字。
是我的逻辑错了吗?
我不确定你是否可以在C中获得NOP,但使用内联汇编可能是可能的。但是,即使您可以在for循环中使用内联汇编编写nop,实际的循环也会生成算术和分支指令。
如果你编译没有优化,你甚至会得到内存负载和存储,这些都是较慢的。
除此之外,在流水线CPU上NOP指令的理论速度应该与CPU频率相同。
实际上,如果你真的想测量,你应该在汇编中编写一个只使用寄存器的循环,在循环中,你可以在单个指令缓存块或几个块中容纳尽可能多的NOP指令。
如果你在C中这样做,用优化gcc -O3
编译,这样for循环计数器只有寄存器,并且还要确保nop不会被优化掉。查看使用gcc -S
的输出组件。