为什么int16 + int16比int16 + int8快?

时间:2014-02-01 19:36:15

标签: c

出于好奇,我决定制作一个基准来测试每种C99类型的速度。

我的基准测试创建了以下结构的数组:

typedef struct 
{
    int x;
    int y;
    short spdx;
    short spdy;
    unsigned char type;
} defaultTypes;

然后我多次对整个结构进行此操作,以模拟游戏更新循环:

while(counter < ARRAY_MAX)
{
    fastStruct[counter].x+=fastStruct[counter].spdx;
    fastStruct[counter].y+=fastStruct[counter].spdy;
    ++counter;
}

我尝试了几种类型,比如int_fast8_t和double。

后来我决定测试一下如果我将“spdx”变量做得更大?所以我做了一个版本,其中位置(x,y)和速度(spdx,spdy)变量都是int16_t

令我惊讶的是,它是SLIGHLY,但仅比int16_t + int8_t版本快得多,它更准确地快了11%(例如比较双,运行int16_t + int16_t版本速度的四分之一)

对于大多数其他速度差异(浮动较慢,较大的变量较慢,等等)我想我知道原因,但我不知道为什么更大的结构(16,16,16,16,8)比较小的更快(即使填充,16,16,8,8,8)。

因此,为什么做int16_t + = int16_t比int16_t + = int8_t快11%?有人建议它与整数推广有关,但我不确定。

重要提示(似乎这会影响结果):我使用MingW编译它,目标是32位,并在64位x86上运行(我只针对64位测试运行一次,因此我不自信其结果,但性能差距似乎是2%而不是11%)

1 个答案:

答案 0 :(得分:0)

我认为答案与您的变量已签名这一事实有关。对于具有相同类型的两个(带符号)变量,cpu可以使用本机指令添加它们。但是,当类型不同时,即使只是不同的大小,它也必须将一个转换为另一个。硬件可能支持也可能不支持,但这仍然是必要的步骤。考虑一下你的int16是256而你的int8是-1。你期望得到一个257的int16值。如果CPU只是将位模式加在一起,那么你会得到一些非常不同的东西,因为-1的8位表示与-1的16位表示不同。首先,它必须将8位数转换为16位数,然后将它们加在一起。

这就是“整数提升”的含义:编译器识别出vars具有不同的类型,并使用适当的汇编代码进行转换。它在执行add操作之前将int8“提升”为int16。

我敢打赌,如果你把它们改成无符号,速度的差异就会消失。