宏定义如何影响性能?

时间:2013-11-07 20:44:08

标签: c++ algorithm matrix macros

我正在研究一个旋转二维数组的项目。当我使用宏来替换某些代码时,结果令人惊讶,因为一切都完全相同。完成任务所需的时间可能会有很大差异。我一直认为宏只是一个占位符,但这怎么可能发生呢?

struct pixel
{
    unsigned short red;
    unsigned short green;
    unsigned short blue;
} ;

//n is the # of elements in the two dimensional array
void rotate1(int n, pixel *src, pixel *dst)
{
    int row, col, max = n - 1;
    for (row = 0; row < n; row++)
        for (col = 0; col < n; col++)
            *(dst+ (((max - row)*n)+col)) = *(src+ (row*n + col));
}

void rotate11(int n, pixel *src, pixel *dst)
{
#define TARGET  *(dst + (((max - row)*n)+col))
#define SOURCE  *(src + (row*n + col))

    int row, col, max = n - 1;
    for (row = 0; row < n; row++)
        for (col = 0; col < n; col++)
        {
            TARGET = SOURCE;
        }

}

结果是:

Time= 2.25 n= 512  Method= rotate1 
Time= 2.18 n= 512  Method= rotate11 

Time= 8.05 n= 1024  Method= rotate1 
Time= 8.08 n= 1024  Method= rotate11 

Time= 25.18 n= 2048  Method= rotate1 
Time= 25.24 n= 2048  Method= rotate11 

Time= 104.38 n= 4096  Method= rotate1 
Time= 104.21 n= 4096  Method= rotate11

Time= 1272.41 n= 8192  Method= rotate1 
Time= 423.00 n= 8192  Method= rotate11

当n很小时,两者的性能相似,但随着n越来越大,rotate11的时间越来越少。

4 个答案:

答案 0 :(得分:7)

就编译器而言,这两个示例完全相同。你在同一次运行中运行这两个例子吗?可能发生的事情是第一个运行的函数(无论你是否使用过宏)都填充了缓存,第二个运行速度要快得多。

如果更改调用函数的顺序,或者每次执行限制为一个函数运行,该怎么办?你应该看到几乎相同的表现。

答案 1 :(得分:1)

我怀疑内存缓存有些影响。为了确保您可以尝试进行4次调用,run1,run11,run 1,run11,您的数据具有内存访问模式,这可能会导致第一次加载数据的成本很高......

答案 2 :(得分:1)

这里有稳定的增长模式 - 正如@mah指出的那样 - 每当你将n增长2倍时,你的运行时间就会增加4倍,这是有道理的,因为你的数组是n ^ 2。

根据这个,你的最后一个电话(n = 8192)应该是〜400长,正如第二个电话确实显示的那样。我愿意打赌在第一次调用(上下文切换或其他一些中断)期间只有一些意外事件导致它停止 - 你应该运行几次迭代并查看它是否重现

答案 3 :(得分:0)

在编译器看到代码之前,C预处理器会扩展宏。

您可以通过gcc中的-E选项创建预处理器输出。

例如:

gcc -E foo.c -o foo.i / *创建预处理器文本文件输出* /

VS

gcc -c foo.c -o foo.o / *创建目标文件输出* /

如果在您选择的编辑器中打开foo.i,您将看到扩展为源代码的MACRO。

我真的不知道MACROS会如何影响你的表现。