Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;循环展开性能_C++_Performance_Templates - Fatal编程技术网

C++ c++;循环展开性能

C++ c++;循环展开性能,c++,performance,templates,C++,Performance,Templates,我在读《C++模板完整指南》这本书,是关于元编程的部分。有一个循环展开的示例(17.7)。我已经实施了点积计算程序: #include <iostream> #include <sys/time.h> using namespace std; template<int DIM, typename T> struct Functor { static T dot_product(T *a, T *b) { return *a

我在读《C++模板完整指南》这本书,是关于元编程的部分。有一个循环展开的示例(17.7)。我已经实施了点积计算程序:

#include <iostream>
#include <sys/time.h>

using namespace std;

template<int DIM, typename T>
struct Functor
{
    static T dot_product(T *a, T *b)
    {
        return *a * *b + Functor<DIM - 1, T>::dot_product(a + 1, b + 1);
    }
};

template<typename T>
struct Functor<1, T>
{
    static T dot_product(T *a, T *b)
    {
        return *a * *b;
    }
};


template<int DIM, typename T>
T dot_product(T *a, T *b)
{
    return Functor<DIM, T>::dot_product(a, b);
}

double dot_product(int DIM, double *a, double *b)
{
    double res = 0;
    for (int i = 0; i < DIM; ++i)
    {
        res += a[i] * b[i];
    }
    return res;
}


int main(int argc, const char * argv[])
{
    static const int DIM = 100;

    double a[DIM];
    double b[DIM];

    for (int i = 0; i < DIM; ++i)
    {
        a[i] = i;
        b[i] = i;
    }


    {
        timeval startTime;
        gettimeofday(&startTime, 0);

        for (int i = 0; i < 100000; ++i)
        {
            double res = dot_product<DIM>(a, b); 
            //double res = dot_product(DIM, a, b);
        }

        timeval endTime;
        gettimeofday(&endTime, 0);

        double tS = startTime.tv_sec * 1000000 + startTime.tv_usec;
        double tE = endTime.tv_sec   * 1000000 + endTime.tv_usec;

        cout << "template time: " << tE - tS << endl;
    }

    {
        timeval startTime;
        gettimeofday(&startTime, 0);

        for (int i = 0; i < 100000; ++i)
        {
            double res = dot_product(DIM, a, b);
        }

        timeval endTime;
        gettimeofday(&endTime, 0);

        double tS = startTime.tv_sec * 1000000 + startTime.tv_usec;
        double tE = endTime.tv_sec   * 1000000 + endTime.tv_usec;

        cout << "loop time: " << tE - tS << endl;
    }

    return 0;
}
#包括
#包括
使用名称空间std;
模板
结构函子
{
静态T点积(T*a,T*b)
{
返回*a**b+函子::点积(a+1,b+1);
}
};
模板
结构函子
{
静态T点积(T*a,T*b)
{
返回*a**b;
}
};
模板
T点积(T*a,T*b)
{
返回函子::点积(a,b);
}
双点积(整数尺寸、双*a、双*b)
{
双res=0;
对于(int i=0;icout根据编译器的不同,如果不启用性能优化,循环展开可能不会发生


原因很容易理解:递归模板实例化基本上是在创建一系列函数。编译器无法将所有这些都转换为内联、展开的循环,并且仍然保持可用的合理调试信息。假设某个函数内部发生SEGFULT,或者引发异常,那么难道你不想得到一个显示每一帧的堆栈跟踪吗?编译器认为你可能想要这样,除非你打开优化,这使你的编译器可以访问你的代码。

“性能…我关闭了所有的代码优化”(用Jamie的声音)这是你的问题!你已经回答了自己的问题:“我关闭了所有代码优化"。如果
dot_product
的实例化没有内联,那么调用它们将比运行循环慢得多。性能度量的第一条规则-使用优化的构建。第二条规则-不要在调试器中运行。还有很多。请注意:循环展开可以有所帮助,但展开级别过多也可能会导致错误指令缓存。这是您正在钻研的微调…谢谢,我已经打开了优化,现在模板速度快多了