- 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/
我正在编写一个应用程序,允许用户创建一个“问卷”,然后向其中添加问题。我正在使用核心数据来存储信息。我创建了一个问卷实体,并与问题实体建立了“一对多”关系。我的问题是,如果要允许用户复制(复制)整个调
有没有办法复制或复制 SharedPreference?或者我需要从一个变量中获取每个变量,然后将它们放入另一个变量中吗? 最佳答案 尝试这样的事情: //sp1 is the shared pref
下面的(A)和(B)有区别吗? (假设 NON ARC,如果重要的话) // --- (A) --- @interface Zoo : NSObject{} @property (copy) Dog
我正在尝试将 mysql SELECT 查询保存到文件中,如下所示: $result = mysqli_query($db,$sql); $out = fopen('tmp/csv.csv', 'w'
我需要创建一个 CVPixelBufferRef 的副本,以便能够使用副本中的值以按位方式操作原始像素缓冲区。我似乎无法使用 CVPixelBufferCreate 或 CVPixelBufferCr
我在 Source 文件夹中有一个 Active wave 录音 wave-file.wav。我需要使用新名称 wave-file-copy.wav 将此文件复制到 Destination 文件夹。
在使用 GNU Autotools 构建的项目中,我有一个脚本需要通过 make 修改以包含安装路径。这是一个小例子: configure.ac: AC_INIT(foobar, 1.0) AC_PR
我想将 SQL 的行复制到同一个表中。但是在我的表中,我有一个“文本”列。 使用此 SQL: CREATE TEMPORARY TABLE produit2 ENGINE=MEMORY SELECT
谁能给我解释一下 df2 = df1 df2 = df1.copy() df3 = df1.copy(deep=False) 我已经尝试了所有选项并执行了以下操作: df1 = pd.DataFram
Hazelcast 是否具有类似于 Ehcache 的复制? http://www.ehcache.org/generated/2.9.0/pdf/Ehcache_Replication_Guide.
我有以下拓扑。一个 Ubuntu 16.04。运行我的全局 MySQL 服务器的 Amazon AWS 上的实例。我想将此服务器用作许多本地主服务器(Windows 机器 MySQL 服务器)的从服务
使用 SQLyog,我正在测试表中是否设置了正确的值。我尝试过 SELECT type_service FROM service WHERE email='test@gmail.com' 因此,只输出
有人可以提供一些关于如何配置 ElasticSearch 进行复制的说明。我在 Windows 中运行 ES,并且了解如果我在同一台服务器上多次运行 bat 文件,则会启动一个单独的 ES 实例,并且
一 点睛 ThreadGroup 复制线程的两个方法。 public int enumerate(Thread list[]) // 会将 ThreadGroup 中的 active 线程全部复制到
一 点睛 ThreadGroup 复制线程组的两个方法。 public int enumerate(ThreadGroup list[]) // 相对于 enumerate(list,true) pu
官方documentation Cassandra 说: Configure the keyspace and create the new datacenter: Use ALTER KEYSPAC
This question already has answers here: How to weight smoothing by arbitrary factor in ggplot2? (2个答
我们有一个表格来表明对各种俱乐部的兴趣。输出将数据记录在 Excel 电子表格中,其中列有他们的首选姓名、姓氏、电子邮件、代词,以及他们感兴趣的俱乐部的相应列中的“1”(下面的模型)。 我们希望为俱乐
This question already has answers here: Closed 8 years ago. Possible Duplicate: In vim, how do I get
如何复制形状及其所在的单元格?当我手动复制时,形状会跟随单元格,但是当我使用宏进行复制时,我会得到除形状之外的所有其他内容。 Cells(sourceRow, sourceColumn).Copy C
我是一名优秀的程序员,十分优秀!