使用条件移动(汇编cmov)来优化?:C中的条件表达式是一种常见的优化.但是,C标准说:
第一个操作数被评估; 在其评估与第二或第三操作数的评估之间存在一个序列点(以评估者为准).仅当第一个操作数不等于0时才评估第二个操作数; 仅当第一个操作数比较等于0时才评估第三个操作数; 结果是第二个或第三个操作数的值(无论哪个被评估),转换为下面描述的类型.110)
例如,以下C代码
#include <stdio.h>
int main() {
int a, b;
scanf("%d %d", &a, &b);
int c= a > b ? a + 1 : 2 + b;
printf("%d", c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将生成优化的相关asm代码,如下所示:
call __isoc99_scanf
movl (%rsp), %esi
movl 4(%rsp), %ecx
movl $1, %edi
leal 2(%rcx), %eax
leal 1(%rsi), %edx
cmpl %ecx, %esi
movl $.LC1, %esi
cmovle %eax, %edx
xorl %eax, %eax
call __printf_chk
Run Code Online (Sandbox Code Playgroud)
根据标准,条件表达式将仅评估一个分支.但是这里对两个分支进行了评估,这违反了标准的语义.这是针对C标准的优化吗?或者许多编译器优化是否与语言标准不一致?
c assembly ternary-operator compiler-optimization language-lawyer
我在 Haskell 邮件列表上遇到了这个讨论。从讨论来看,添加liftA2 作为Applicative 的方法似乎对性能有影响。你能提供具体的例子,为什么需要在 Applicative 方法中添加 liftA2 吗?
我正在阅读关于Haskell wiki 的类别类别.当我遇到作为仿((,) e)函数实例的类型类时,我很困惑.据作者说
((,) e)表示一个容器,它包含e类型的"注释"及其保存的实际值.
但是,我不太明白这句话的意思,因为我在这里只能看到一个分段的元组.我还在Hoogle上搜索了这个类型类,但一无所获.