【发布时间】:2019-07-17 20:44:36
【问题描述】:
我使用 GCC 的 "asm" 关键字在 C 中编写了一个简单的乘法函数,并在汇编代码中编写了另一个函数。
我计算了它们每个的执行时间,虽然它们的时间非常接近,但 C 函数比汇编代码中的快一点。
我想知道为什么,因为我希望 asm 更快。是因为对 GCC 的“asm”关键字有额外的“调用”(我不知道该用什么词)吗?
这里是 C 函数:
int multiply (int a, int b){return a*b;}
这是C文件中的asm:
int asmMultiply(int a, int b){
asm ("imull %1,%0;"
: "+r" (a)
: "r" (b)
);
return a;
}
我的主要时间:
int main(){
int n = 50000;
clock_t asmClock = clock();
while(n>0){
asmMultiply(4,5);
n--;
}
asmClock = clock() - asmClock;
double asmTime = ((double)asmClock)/CLOCKS_PER_SEC;
clock_t cClock = clock();
n = 50000;
while(n>0){
multiply(4,5);
n--;
}
cClock = clock() - cClock;
double cTime = ((double)cClock)/CLOCKS_PER_SEC;
printf("Asm time: %f\n",asmTime);
printf("C code time: %f\n",cTime);
谢谢!
【问题讨论】:
-
表达你如何测量程序中经过的时间。
-
“是不是因为对 GCC 的“asm”关键字有额外的“调用”(我不知道该用什么词)?” - 不,是因为你的 asm 很慢。不要在琐碎的代码上与编译器竞争,他们会在 99% 的情况下用完美的机器代码击败你(通常优化得非常好,它可能会让你感到困惑并且看起来很慢 - 如果你的机器知识是不是所需的专业知识,并且您可能对现代 x86 的工作方式有一些幼稚的假设)。提升你的机器知识(假设你的问题措辞和内容是初学者,达到“专家”或“大师”)并使用一些中等复杂的 C 源代码 = 你可以赢。
-
@Ped7g:使用
asm("imul %1, %0" : "+r"(a) : "rme"(b) );为编译器提供寄存器、内存或立即数的选择@ GCC 擅长于此,但如果可以选择,clang 通常会选择内存,即使这意味着溢出register var first :/ 但是不,如果任一输入是一个常数,可以用LEA或 shift 来完成,例如9或5,或者2. 或作为 LEA 的一部分折叠成一个附加组件。 (但可能类似肯定)。 gcc.gnu.org/wiki/DontUseInlineAsm -
您一直在使用不同的基准测试代码编辑您的问题,但您仍然没有显示任何实际时间结果、编译器版本/选项或硬件信息。 C 不是凭空存在的,编译器版本/选项和硬件都很重要。您更新的代码仍然无法阻止
multiply()完全优化。见CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!"
标签: c gcc assembly time inline-assembly