- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
完全知道these completely artificial benchmarks don't mean much,我对“四大”编译器选择的几种方式进行编译感到有些惊讶。
struct In {
bool in1;
bool in2;
};
void foo(In &in) {
extern bool out1;
extern bool out2;
out1 = (in.in1 == true);
out2 = in.in2;
}
foo(In&): # @foo(In&)
mov al, byte ptr [rdi]
mov byte ptr [rip + out1], al
mov al, byte ptr [rdi + 1]
mov byte ptr [rip + out2], al
ret
== true
比较是多余的,因此这两种分配都是从一个内存位置到另一内存位置的直接副本,通过
al
传递,因为没有内存到内存
mov
。
foo(In&):
movzx eax, BYTE PTR [rdi]
mov BYTE PTR out1[rip], al
movzx eax, BYTE PTR [rdi+1]
mov BYTE PTR out2[rip], al
ret
mov
存入“small”寄存器,而是将
movzx
存为完整的
eax
。
为什么?这是为了完全重置寄存器重命名器中的eax
和子寄存器的状态,以避免部分寄存器停顿吗?
in$ = 8
void foo(In & __ptr64) PROC ; foo, COMDAT
cmp BYTE PTR [rcx], 1
sete BYTE PTR bool out1 ; out1
movzx eax, BYTE PTR [rcx+1]
mov BYTE PTR bool out2, al ; out2
ret 0
void foo(In & __ptr64) ENDP ; foo
cmp
和
sete
和内存操作数,因此可以说中间寄存器是FLAGS)。
bool
的东西)还是由于某些已知的固有限制-例如bool
在前端之后立即被视为无特殊属性的纯字节吗? cmp
的结果不会更改代码路径),所以我希望这样做不会花费那么多,特别是与访问内存相比。 错过的优化有多昂贵? foo(In&):
xor eax, eax #9.5
cmp BYTE PTR [rdi], 1 #9.5
mov dl, BYTE PTR [1+rdi] #10.12
sete al #9.5
mov BYTE PTR out1[rip], al #9.5
mov BYTE PTR out2[rip], dl #10.5
ret #11.1
sete
通过al
而不是直接进入内存; 有什么理由喜欢这个吗? eax
清零? 部分寄存器再次停止?但是dl
没有得到这种治疗... == true
,而ICC现在可以
foo(In&):
mov al, BYTE PTR [rdi] #9.13
mov dl, BYTE PTR [1+rdi] #10.12
mov BYTE PTR out1[rip], al #9.5
mov BYTE PTR out2[rip], dl #10.5
ret #11.1
eax
不会归零,但仍使用两个寄存器,并且“首先并行开始读取,以后使用所有结果”。
sete
有什么特别之处,使ICC认为值得将eax
归零? 最佳答案
TL:DR:gcc的版本在所有x86 uarch上都是最可靠的,避免了虚假的依赖关系或多余的内容。 它们都不是最佳选择。一次加载两个字节应该更好。
这里的两个关键点是:
tune=generic
相关。 (Knight's Corner的较早的Xeon Phi使用基于Pentium P54C的改进型有序内核,而有序Atom系统可能仍然存在,但现在也已过时。在这种情况下,在两次测试之后都进行存储很重要加载,以允许在加载中进行内存并行化。)mov al, [rdi]
解码为微融合的ALU +加载uop,它将加载结果合并到RAX中。 (这对于位域合并很有用,而不是让前端在读取完整的寄存器时插入一个稍后的合并uop会产生额外的开销)。
add al, [rdi]
或
add rax, [rdi]
相同。 (这只是8位加载,但它依赖于RAX中旧值的全宽。对低8/低16 regs的仅写指令(例如
al
或
ax
)并非仅写至有关微体系结构。)
rdi
,负载就会立即发生。存储地址也是已知的,因此可以执行存储地址指令(因此以后的加载/存储可以检查重叠),但是存储数据指令被卡住以等待合并指令。 (Intel上的商店始终是2个独立的uops,但它们可以在前端一起微熔断。)
or al,dl
而不是
or eax,edx
保存任何代码大小,例如。
movzx
具有2字节的操作码)。
movzx eax, byte ptr [mem]
? movzx eax, m8/m16
完全在加载端口中处理,而不是作为负载+ ALU-零扩展处理。唯一的额外费用是1个字节的代码大小。 (Zen之前的AMD对于movzx负载有1个额外的延迟周期,显然,它们必须在ALU和负载端口上运行。现代的做法是将符号/零扩展或广播作为负载的一部分,而没有额外的延迟不过)
pxor xmm0,xmm0
在
cvtsi2ss/sd xmm0, eax
之前,因为Intel的设计不良的指令集合并到了目标XMM寄存器的低位qword中。 (PIII的短视设计将128位寄存器存储为2个64位的一半,因此如果Intel在 future 的CPU中对其进行设计,则int-> FP转换指令将对PIII产生额外的影响,以将高位一半归零。心神。)
out2
读取此核心上的负载。 (x86强大的内存排序规则通过在
out1
的存储之前提交到存储缓冲区来防止以后的存储在全局范围内可见,但是在内核/线程内进行存储转发仍然有效。)
cmp/setcc
:MSVC/ICC只是愚蠢的 movzx
是避免它的更好方法。
bool
保证为0或1,而不是0/非零。
x == true
的
x
必须与
bool x
相同,因此(除非实现在结构vs.
extern bool
中使用了不同的对象表示规则),它始终可以仅复制对象表示(即字节)。
bool
使用一个1字节的0/非0(而不是0/1)对象表示形式,则需要使用
cmp byte ptr [rcx], 0
在
(int)(x == true)
中实现 bool 化,但是在这里您要分配给另一个
bool
,因此它可以复制。而且我们知道它没有 bool 值0/非零,因为它与
1
进行了比较。我认为这不是故意针对无效的
bool
值进行防御,否则为什么不为
out2 = in.in2
这样做呢?
bool
并不出色。
Boolean values as 8 bit in compilers. Are operations on them inefficient?。有些比其他更好。
setcc
直接存储到内存还不错,但是cmp + setcc是2个不需要发生的不必要的ALU uops。 显然在Ryzen上,
setcc m8
是1 uop,但每2个时钟吞吐量1个。所以这很奇怪。甚至是Agner的错字? (
https://agner.org/optimize/)。在Steamroller上,每个时钟1 uop/1。
setcc m8
是2个融合域uops,每时钟吞吐量1个。
int
的隐式转换,或者是否为
==
操作数定义了
bool
。
setcc
放入寄存器,则首先对其进行异或为零不是一个坏主意,因为
movzx eax,mem
比
mov al,mem
更好。即使您不需要结果零扩展到32位。
xor
-zero/cmp/setcc进行比较几乎没有意义,但使用
mov al, [m8]
进行非比较则毫无意义。 xor-zero是直接使用
movzx
加载来打破错误的依赖关系的等效项。
while(*ptr++ != 0){}
之类的搜索循环,而gcc/clang只能以第一次迭代之前已知的跳闸计数自动vec循环)。
但是,ICC在像这样的小微优化方面并不出色;它的asm输出通常看起来比gcc或clang更像是源(不利于它)。
setcc al
/
movzx eax,al
进行 bool 化,但最近的更改已使其在存在可以提前归零的自由寄存器时使用
xor eax,eax
/set-flags/
setcc al
消除了关键路径的零扩展。任何设置标志。 (异或归零还会写入标志)。
passing through
al
as there's no memory to memorymov
.
foo(In &):
mov rsi, rdi
lea rdi, [rip+out1]
movsb # read in1
lea rdi, [rip+out2]
movsb # read in2
foo(In &):
movzx eax, word ptr [rdi] # AH:AL = in2:in1
mov [rip+out1], al
mov [rip+out2], ah
ret
in.in2
是新高速缓存留置权的第一个字节)。这可能需要额外的10个周期。或在Skylake之前的版本中,如果它也跨越4k边界,则损失可能是100个周期的额外延迟。但是除此之外,x86还具有有效的未对齐负载,并且通常可以通过合并狭窄的负载/存储来节省成本,这是一个胜利。 (gcc7和更高版本通常在初始化多个结构成员时执行此操作,即使在不知道它不会越过缓存行边界的情况下也是如此。)
In &in
不能别名extern bool out1, out2
,因为它们具有静态存储和不同类型。
bool
的指针,那么您将不知道(没有
bool *__restrict out1
)它们没有指向
In
对象的成员。但是静态
bool out2
不能为静态
In
对象的成员添加别名。然后,除非先检查重叠,否则在编写
in2
之前先阅读
out1
并不安全。
关于c++ - 将 bool 值从参数复制到全局值-比较编译器输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52321370/
我有一个带有列的表提供者 implied(tiny int)(something like nullable bool) provi
我正在阅读 VideoFileWriter来自 AForge.Video.FFMPEG 的类(class)通过 ILSPY 组装(我很想看看特定方法是如何工作的)并发现了这个: public bool
这是我的完整代码... import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import
我有一个输入 list类型 [Maybe SomeType]和一个谓词 p类型 SomeType -> Bool ,我想回答这个问题“谓词 p 是否适用于所有碰巧在输入中的 SomeType ?”。
使用 !!x 有什么区别吗?对比(bool)x ? 假设__STDC_VERSION__ >= 199901L和 #include 他们都保证结果是0吗?或 1 ,并且无论 x 的大小和值如何,都不
我正在编写一些 C++ 代码,我想调用两个函数(checkXDirty 和 checkYDirty),并返回 true如果任一返回 true。即使一个返回 true 我也需要评估两者,所以我的第一个想
我注意到 bool在 QtCreator 中以不同于其他类型的颜色突出显示: 只有在包含某些 header 时才会发生这种情况,最终我将其追踪到 . QtCreator 的代码检查器似乎无法手动跟踪
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
训练神经网络学习“异或” 我正在尝试使用“批量归一化”,我创建了一个批量归一化层函数“batch_norm1”。 import tensorflow as tf import nump
我已经创建了任务函数来验证我的 json 文件。一切正常,直到我没有使用结果。当我试图从 async task function 获得结果时它显示错误为 Cannot implicitly conve
我有一个函数 func login (parameters: [(String, Any)], completion: @escaping (Bool) -> Vo
我正在处理最近从 X/Motif 转移到 Qt 的 C++ 代码库。我正在尝试编写一个 Perl 脚本,它将用 bool 替换所有出现的 Boolean(来自 X)。该脚本只是做了一个简单的替换。 s
嗨,我正尝试创建一个Visiblity小部件,如果用户在Firebase数据库阵列上,该小部件将显示。看起来像这样(成员数组): 如您所见,我创建了一个StreamBuilder,如果当前用户的用户名
我创建了如下的rest api方法, Future activateAccount(int id, int code) async{ final body = {"code": '$c
在我的Flutter应用中,我有一个返回Future的函数,但我想将结果作为Stream。这是函数: Future isGpsOn() async { if (await Geolocat
我可以看到 BOOLEAN 覆盖了 __visit_name__ class BOOLEAN(Boolean): __visit_name__ = 'BOOLEAN' 控制调度员选择的访问者方
考虑以下代码: bool x; bool? y = null; x = y?? true; 将 bool? 分配给 bool 是一个编译时错误,但上面的代码在编译和运行时都成功了。为什么?尽管第三条语
我正在重写一些 Javascript 代码以在 Excel VBA 中工作。由于在这个网站上搜索,我已经设法翻译了几乎所有的 Javascript 代码!但是,有些代码我无法准确理解它在做什么。这是一
我想拍一张bool来自Vec并在 if 语句中进行比较。如何解决以下错误? | 7 | if cell { | ^^^^ expected
我在我的应用程序崩溃跟踪工具中发现了一些崩溃。基本上我有一个 tabBarController,其中一个选项卡有一个嵌入式 UIWebView,另一个选项卡有一个带有 UITableView 的 Co
我是一名优秀的程序员,十分优秀!