c++ - atoi() 和 atof() 缓存吗?它们似乎执行得越快,调用的次数越多

标签 c++ c performance caching optimization

我使用 _rdtsc()atoi()atof() 进行计时,我注意到它们花费了很长时间。因此,我编写了自己的这些函数版本,这些版本比第一次调用要快得多。

我使用的是 Windows 7 VS2012 IDE,但使用的是 Intel C/C++ 编译器 v13。我启用了 -/O3 和 -/Ot (“喜欢快速代码”)。我的 CPU 是 Ivy Bridge(移动)。

经过进一步调查,似乎 atoi()atof() 被调用的次数越多,它们执行得越快??我说的速度更快:

当我从循环外部调用 atoi() 时,仅一次,它需要 5,892 个 CPU 周期,但经过数千次迭代后,这减少到 300 - 600 个 CPU 周期(相当大的执行时间范围)。

atof() 最初需要 20,000 到 30,000 个 CPU 周期,然后在几千次迭代后它需要 18 到 28 个 CPU 周期(这是我的自定义函数第一次使用的速度时间)。

有人能解释一下这个效果吗?

编辑:忘了说-我的程序的基本设置是从文件中解析字节的循环。在循环内部,我显然使用我的 atof 和 atoi 来注意上述内容。但是,我还注意到,当我在循环之前进行调查时,只调用了两次 atoi 和 atof,以及两次用户编写的等效函数,这似乎使循环执行得更快。该循环处理了 150,000 行数据,每行需要 3 个 atof()atoi()。再一次,我无法理解为什么在我的主循环之前调用这些函数会影响程序调用这些函数 500,000 次的速度?!

#include <ia32intrin.h>

int main(){
    
    //call myatoi() and time it
    //call atoi() and time it
    //call myatoi() and time it
    //call atoi() and time it

    char* bytes2 = "45632";
    _int64 start2 = _rdtsc();
    unsigned int a2 = atoi(bytes2);
    _int64 finish2 = _rdtsc();
    cout << (finish2 - start2) << " CPU cycles for atoi()" << endl;
    
    //call myatof() and time it
    //call atof() and time it
    //call myatof() and time it
    //call atof() and time it
    
    
    //Iterate through 150,000 lines, each line about 25 characters.
    //The below executes slower if the above debugging is NOT done.
    while(i < file_size){
        //Loop through my data, call atoi() or atof() 1 or 2 times per line
        switch(bytes[i]){
            case ' ':
                //I have an array of shorts which records the distance from the beginning
                //of the line to each of the tokens in the line. In the below switch
                //statement offset_to_price and offset_to_qty refer to this array.

            case '\n':
                
                switch(message_type){  
                    case 'A':
                        char* temp = bytes + offset_to_price;
                        _int64 start = _rdtsc();
                        price = atof(temp);
                        _int64 finish = _rdtsc();
                        cout << (finish - start) << " CPU cycles" << endl;
                        //Other processing with the tokens
                        break;

                    case 'R':
                        //Get the 4th line token using atoi() as above
                        char* temp = bytes + offset_to_qty;
                        _int64 start = _rdtsc();
                        price = atoi(temp);
                        _int64 finish = _rdtsc();
                        cout << (finish - start) << " CPU cycles" << endl;
                        //Other processing with the tokens
                        break;
                }
            break;
        }
    }
}

文件中的行是这样的(中间没有空行):

34605792 R dacb 100

34605794 A racb S 44.17 100

34605797 R kacb 100

34605799 A sacb S 44.18 100

34605800 R nacb 100

34605800 A tacb B 44.16 100

34605801 R gacb 100

我在“R”消息中的第 4 个元素和“A”消息中的第 5 个元素上使用 atoi(),并在第 4 个元素上使用 atof()在“A”消息中。

最佳答案

我猜你为什么看到 atoiatof 有如此大的改进,而不是你自己的更简单的功能,是因为前者有一个大量分支以处理所有边缘情况。前几次,这会导致大量不正确的分支预测,代价高昂。但几次之后,预测变得更加准确。正确预测的分支几乎是免费的,这将使它们与您的不包括开始的分支的简单版本竞争。

缓存当然也很重要,但我认为这不能解释为什么您自己的函数从一开始就很快,并且在重复执行后没有看到任何相关的改进(如果我理解正确的话)。

关于c++ - atoi() 和 atof() 缓存吗?它们似乎执行得越快,调用的次数越多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19334562/

相关文章:

c# - .NET:Windows 窗体/控件性能

c++ - 检查 STL 中的空交集

performance - 要设置的 Oracle 兼容参数

c++ - isnan 无法与 `-Ofast` 标志一起正常工作

c - sdcc 不接受代码

C - 从 C++ 模拟 'mutable'

c - 带有结构体数组的 float ?

php - MySQL 过程 - 增量地重新计算行

C++:参数与参数之间的区别?

c++ - 如果我将 p!=nullptr 更改为 *p! ='\0' ,然后就可以了,但是为什么呢?