我需要对减法结果进行平方,并且需要速度快。
我已经确定了一些可能的方法,但我想听听优点和缺点
unsigned int a = 5;
unsigned int b = 7;
/* Approach 1a */
unsigned int c = (a - b) * (a - b);
/* Approach 1b */
int d = (a - b);
unsigned int e = d * d;
/* Approach 2a */
unsigned int f = abs(a - b) * abs(a - b);
/* Approach 2b */
unsigned int g = abs((a - b) * (a - b));
/* Approach 2c */
unsigned int h = abs(a - b);
unsigned int i = h * h;
/* Approach 3a */
unsigned int j = (a > b) ? ((a - b) * (a - b)) : ((b - a) * (b - a))
Run Code Online (Sandbox Code Playgroud)
我不确定如何确保编译器不会优化的随机负数,所以我只写了一般概念。我确信只需查看一些解决方案就可以将它们挑出为(次)最优的。
作为一般规则,您应该避免分支来制作快速程序。因此,使用额外的abs条件运算符并不好。
还要相信你的编译器会进行优化。
我使用带有选项的 x86-64 gcc 13.1在Compiler Explorer上测试了代码的稍微修改版本-O2。
#include <stdlib.h>
unsigned int hoge(unsigned int a, unsigned int b) {
/* Approach 1a */
unsigned int c = (a - b) * (a - b);
/* Approach 1b */
int d = (a - b);
unsigned int e = d * d;
/* Approach 2a */
unsigned int f = abs(a - b) * abs(a - b);
/* Approach 2b */
unsigned int g = abs((a - b) * (a - b));
/* Approach 2c */
unsigned int h = abs(a - b);
unsigned int i = h * h;
/* Approach 3a */
unsigned int j = (a > b) ? ((a - b) * (a - b)) : ((b - a) * (b - a));
/* test c, e, f, g, i, j here */
return c;
}
Run Code Online (Sandbox Code Playgroud)
在此设置中,未使用的方法将被优化掉。
返回c、e、f、 和g会得到相同的结果:
hoge:
movl %edi, %eax
subl %esi, %eax
imull %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
返回的i结果是:
hoge:
subl %esi, %edi
movl %edi, %eax
negl %eax
cmovs %edi, %eax
imull %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
返回的j结果是:
hoge:
cmpl %edi, %esi
jnb .L2
movl %edi, %eax
subl %esi, %eax
imull %eax, %eax
ret
.L2:
movl %esi, %eax
subl %edi, %eax
imull %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
从这个测试中,我们可以说方法1a、1b、2a、2b应该具有相同的性能,而方法2c和3a的性能会比它们差。
请注意,结果应取决于编译器、选项和目标机器。
我认为方法 1b 是最好的方法,因为它简单并且a - b不需要手动重复计算。
如果您想要更快的操作,您可以选择使用 SIMD 操作或 GPU。
| 归档时间: |
|
| 查看次数: |
119 次 |
| 最近记录: |