每秒NOP指令数

时间:2016-11-05 00:52:21

标签: c assembly

我正在编写一个程序来确定每秒可以运行多少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: %lu\n", 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: %lu\n", 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("%lu\n", ((numberOfRuns * 100) / avgTime) * 1000000);
}

我要做的第一件事是运行一个由100个NOP指令0xffffffff时间组成的汇编循环,并存储它在nopTime中所用的时间。然后,我也这样做,而是调用刚刚返回的汇编函数。

我相信如果不是更多,我应该每秒至少获得1,000,000,000个NOP指令,但我甚至都不接近。这是我上次运行的输出:

NOP Seconds: 251077086
RET Seconds: 10450449
/* Calculated number of NOPs per second */
17000000

我不太习惯使用更大的数据类型,所以事情被截断了,我没有意识到这一点?我应该使用双打吗?似乎当我搞乱数据类型时,我会得到不同的数字,但它们也是相当小的数字。

我的逻辑错了吗?

1 个答案:

答案 0 :(得分:1)

我不确定你是否可以在C中获得NOP,但可能使用内联汇编。但即使您可以使用内联汇编在for循环内编写NOP,实际循环也会生成算术和分支指令。

如果你在没有优化的情况下编译,你甚至会得到内存加载和存储,而且速度较慢。

除此之外,NOP的理论速度和流水线CPU上的NOP指令应该与CPU频率相同。

出于实际目的,如果你真的想要测量,你应该在只使用寄存器的汇编中编写一个循环,并且在循环内部你有NOP指令,就像它们适合单个指令缓存块或者几个块一样

如果你在C中执行此操作,请使用优化gcc -O3进行编译,这样for循环计数器只是寄存器,并且还要确保NOP不会被优化掉。使用gcc -S查看输出程序集。