为什么显式的位移位算法会导致更大的.s文件
why does explicit bit shifting arithmetic result in a bigger .s file?
我不是一个受过训练的计算机科学家,所以我不知道编译等方面的全部或大部分细节,但我一直认为我的c程序被编译成机器代码,我可以使用gcc使用-S标志查看这些代码。
我还认为我的代码越像机器代码,计算机执行它的速度就越快。所以我决定测试一下。
我写了两个测试文件来计算一道简单的算术题。
// test1.c
int main(int argc, char* argv[]){
int x = 4243;
int y = 3235;
int z = 613*x + 725*y;
return 0;
}
// test2.c
int main(int argc, char* argv[]){
int x = 4243;
int y = 3235;
int z = ( ( ( ( ( ( ( x << 3 ) + x ) << 1 ) + x ) << 3 ) + x ) << 2 ) + x +
( ( ( ( ( ( ( ( ( y << 2 ) + y ) << 1 ) + y ) << 2 ) + y ) << 2 ) + y ) << 2 ) + y;
return 0;
}
我知道我把这个例子做得比必要的要复杂得多,但当我用一个更简单的例子来尝试时,区别并没有那么明显。
现在,如果我使用gcc-S标志进行编译,那么test1.S的机器代码是31行,test2.S的的机器代码为47行
可能的解释是什么?机器代码行数减少意味着执行速度加快的假设有缺陷吗?在创建二进制文件之前,.s文件是否用于任何用途?我的玩具测试是假的吗?
感谢您的任何见解
曾经有一段时间,CPU非常简单,像上面尝试的比特移位技巧实际上可以比CPU的内置乘法指令产生更好的性能。(以牺牲程序长度为代价:一系列移位指令可能比一条乘法指令快,也可能不快,但肯定会更长。)我相信这一点一直持续到80286年。
甚至曾经有一段时间(还记得Z80吗?)CPU非常简单,甚至没有内置的乘法指令,所以我们必须调用例程来乘法,这些例程当然会包含循环,循环的迭代次数与被相乘的数字的位数一样多,所以这些移位技巧会产生很多,那时的表现要好得多。(同样,这将以牺牲程序长度为代价:调用乘法例程比执行两个或多个移位操作占用更少的字节。)
但如今,这种说法已不再成立。你的(可能是现代的)CPU当然有一个内置的乘法指令,它名义上在非常少的时钟周期内执行(小,如3),所以使用它一定会比将乘法分解为多个移位运算运行得更快(更小),每个移位运算名义上在一个时钟周期内运行。
我之所以说"名义上",是因为有了预取、流水线、缓存等,即使你可以提前知道任何给定指令需要多少时钟周期的想法也不再成立。
所以,长话短说:"学会停止担忧,爱上炸弹"。
如果您正在为一个没有乘法指令的CPU(这样的CPU确实存在)编写,并且如果您必须多次计算613*x + 725*y
,那么编写自定义移位代码可能是值得的。
但您可能必须用汇编语言编写它,使其比编译器内置的乘法函数更快。
- C++文件传输的校验和算法
- 在C++中使用算法头文件时出错
- 适用于大文件和 512 KB 块的最快和轻量级哈希算法 [C,Linux,MAC,Windows]
- 为什么显式的位移位算法会导致更大的.s文件
- 使用BinarySearch算法的C++函数(.bin文件)
- C++循环算法不正确(或文件处理问题)
- C++,用于在大文件中的行上搜索单词的算法
- 用C++算法将.csv文件转换为结构
- DTW算法OCT文件
- 如何使用条带化算法读取住宅.dat文件C++
- EM算法,读取并保存XML文件
- 如何使用 Prim 算法从输入文件中查找具有给定坐标集的最小生成树?
- 如何将输入文件中的坐标与 prim 算法一起使用,以便使用pygraphics和C++创建圆?
- 我的算法只是将第一个单词写入文件
- 通过算法头文件中定义的 sort() 函数对 c++ 中的元素对结构数组进行排序
- 从文本文件中简单读取算法不起作用
- 尝试对结构向量进行排序时,我在算法文件中收到 20 个错误。我不知道怎么了?
- C++文件分析器/stdin输入-这个算法会起作用吗
- 用于查找文件的C++算法
- Emscripten:找不到算法.h文件