- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这里是新手...
我正在测试具有嵌套逻辑的例程的两种实现:一种是朴素的实现,另一种是我巧妙地尝试删除一些分支的实现。我在 x86 Merom 上使用“gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3”,gcc 选项为“-ffast-math -fomit-frame-pointer -msseregparm -mfpmath=sse -msse2”。代码如下:
#define math_sign(a) ( (a) < .0f ? -1.f : +1.f )
inline float math_interp_clamp(float a, float slope, float target)
{
#if 0
// 5 instr, 1 branch
float b = a + slope;
return slope > 0.f ? (b > target ? target : b) : (b < target ? target : b);
#else
// 19 instr
float b = a + slope;
return ( b - target ) * math_sign( slope ) > 0.f ? target : b;
#endif
}
启用 ifdef 后,我得到:
math_interp_clamp:
.LFB505:
.cfi_startproc
comiss .LC7, %xmm1
addss %xmm1, %xmm0
jbe .L44
minss %xmm0, %xmm2
movaps %xmm2, %xmm0
ret
.L44:
maxss %xmm0, %xmm2
movaps %xmm2, %xmm0
ret
.cfi_endproc
在禁用 ifdef 的情况下,我得到:
math_interp_clamp:
.LFB505:
.cfi_startproc
xorps %xmm5, %xmm5
addss %xmm1, %xmm0
movss .LC3, %xmm4
cmpltss %xmm5, %xmm1
movss .LC2, %xmm6
movaps %xmm0, %xmm3
andps %xmm1, %xmm4
andnps %xmm6, %xmm1
subss %xmm2, %xmm3
orps %xmm4, %xmm1
mulss %xmm1, %xmm3
movaps %xmm5, %xmm1
cmpltss %xmm3, %xmm1
movaps %xmm2, %xmm3
movaps %xmm1, %xmm2
andps %xmm1, %xmm3
andnps %xmm0, %xmm2
orps %xmm3, %xmm2
movaps %xmm2, %xmm0
ret
.cfi_endproc
我实际上并没有为生成的代码计时,但基于循环计数,我无法想象这 19 条指令比单纯的分支更快......我应该多么无情地避免分支,或者我正在使用gcc 错了吗?
我们慷慨地接受了一个很好的计时方法或 sse 教程的链接。
最佳答案
gcc 4.9.2 将无分支版本编译为 16 条指令。或者像你一样的 19 个 -m32 -msse
但不是 -m32 -msse2
.这些指令中有相当多的并行性,但不幸的是,FP 逻辑(如 orps
)只能在当前英特尔设计中的单个端口上运行。 (与能够接受 por
微指令的所有 3 个 vector ALU 端口相比。)
gcc 使用 -O3 -ffast-math
无分支地编译您的“原始”版本. (没有 -ffast-math
,它仍然使用分支。我没有检查位操作以查看即使使用 NaN 结果是否相同。)可能有一种方法可以编写您的原始版本,以便它可以制作无分支版本即使没有-ffast-math
.也许通过 !(b < target)
而不是 b > target
,所以 NaN 处理是一样的? IDK.
math_interp_clamp: # gcc 4.9.2 -O3 -ffast-math
.LFB0:
addss %xmm1, %xmm0
movaps %xmm0, %xmm3
maxss %xmm2, %xmm3
minss %xmm0, %xmm2
pxor %xmm0, %xmm0
cmpltss %xmm1, %xmm0
andps %xmm0, %xmm2
andnps %xmm3, %xmm0
orps %xmm2, %xmm0
ret
这很可能是一次胜利,除非分支是非常可预测的(即值几乎不需要限制)。你最好的是-fprofile-generate
/-fprofile-use
, 让编译器决定。
出于好奇,我查看了 x87 的无分支版本 ( -m32 -O3
)。即使 x87 有 fcmovbe
,它仍然编译为 19 个 insns,因为 x87 需要额外的指令来弹出堆栈(并且函数 args 不以 regs 开头)。
没有cmov
基于 xmm 寄存器的标志。打包cmov
用 andps / pand
完成或 blendv
基于掩码寄存器。
关于c - 天真的梯形逻辑比因式逻辑更好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23210858/
当你进入页面http://m.google.com使用 Mobile Safari,您会在页面顶部看到漂亮的栏。 我想像那样画一些梯形(美国:梯形),但我不知道怎么画。我应该使用 css3 3d 转换
它基本上是一个 flex 的 div: 那么可以只使用 CSS 而不使用图像吗? 最佳答案 嗯...我是这个形状最大的怀疑者,但它似乎是可能的 O_o Demo HTML CSS .shape
我希望在 Java 中创建一个星号梯形,就像下面使用嵌套 for 循环的模式一样。 ** **** ******** 我知道如何打印两个、四个然后六个星号,如下面的代码所示。但是,我不知道如何创建两个
关于 Python 中实时数据的数值积分(梯形)的问题- 背景:实时测量一个平均速度为 100 米/分钟的移动物体,我每 100 毫秒采样一次,持续 60 秒 - 因此在一分钟结束时,我将获得 600
我很难解决这个问题: 我想用 css 做这个: 如图:两个圆 Angular 的飞人(重要!),一个带文字的飞人,一个带图片,或者图标的飞人,有图标的飞人尺寸可以细一些,但是两个飞人必须是大小相同。
我想创建一个响应式梯形形状,它可以是 CSS、SVG 或 Canvas。 我已经能够创建三 Angular 形,但不能创建响应式的梯形。 div { width: 0; height: 0;
这个问题在这里已经有了答案: css skew element and get inner rounded border top (1 个回答) 关闭 4 年前。 我想用 CSS 和 HTML 自定
这是 css 在 id 上的代码工作正常: border-bottom: 100px solid #0000ff80; border-right: 50px solid transparent; he
我在使用 CSS 时遇到了一个小问题。我需要一个梯形 div,它的左上角( Angular 大于 90 度的那个)是圆 Angular 的。我已经知道了: HTML: CSS: .tr
我在使用 CSS 时遇到了一个小问题。我需要一个梯形 div,它的左上角( Angular 大于 90 度的那个)是圆 Angular 的。我已经知道了: HTML: CSS: .tr
我有这个带有伪元素的形状: https://jsfiddle.net/6gf1m3j5/ body { margin: 0; background:#ccc; } #octagon-l
我在使用 CSS 时遇到了一个小问题。我需要一个梯形 div,它的左上角( Angular 大于 90 度的那个)是圆 Angular 的。我已经知道了: HTML: CSS: .tr
我怎样才能像这里的 Tidal 一样制作一个旋转的横幅 我试过制作梯形并根据 http://browniefed.com/blog/the-shapes-of-react-native/ 将其旋转 4
我正在使用 three.js 制作一个小动画,其中有一些基本的 3D 模型,其中一个我正在努力处理的是“梯形 ”。 到目前为止,我只能在 THREE.CylinderGeometry 的帮助下创建截顶
我正在使用 three.js 制作一个小动画,其中有一些基本的 3D 模型,其中一个我正在努力处理的是“梯形 ”。 到目前为止,我只能在 THREE.CylinderGeometry 的帮助下创建截顶
我是一名优秀的程序员,十分优秀!