- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我在IvyBridge上进行以下设置,我将在注释位置插入测量有效载荷代码。 buf
的前8个字节存储buf
本身的地址,我用它来创建循环承载的依赖项:
section .bss
align 64
buf: resb 64
section .text
global _start
_start:
mov rcx, 1000000000
mov qword [buf], buf
mov rax, buf
loop:
; I will insert payload here
; as is described below
dec rcx
jne loop
xor rdi, rdi
mov rax, 60
syscall
mov qword [rax+8], 8
mov rax, [rax]
perf
显示循环为5.4c/iter。这有点可理解,因为L1d延迟是4个周期。
mov rax, [rax]
mov qword [rax+8], 8
mov
指令:
mov rax, [rax]
mov qword [rax+8], 8
mov rbx, [rax+16]
mov
如何将速度从9c/iter提高到6.8c/iter?
rax+8
。如果将
rax+8
更改为
rax+16
或
rax+24
,则情况1和2的结果相同。但是,当将其更改为
rax+32
时,会发生一些令人惊讶的情况:案例1变为5.3c/iter,案例2突然变为4.2c/iter。
perf
事件:
$ perf stat -ecycles,ld_blocks_partial.address_alias,int_misc.recovery_cycles,machine_clears.count,uops_executed.stall_cycles,resource_stalls.any ./a.out
[rax+8]
的情况1:
5,429,070,287 cycles (66.53%)
6,941 ld_blocks_partial.address_alias (66.75%)
426,528 int_misc.recovery_cycles (66.83%)
17,117 machine_clears.count (66.84%)
2,182,476,446 uops_executed.stall_cycles (66.63%)
4,386,210,668 resource_stalls.any (66.41%)
[rax+8]
:
9,018,343,290 cycles (66.59%)
8,266 ld_blocks_partial.address_alias (66.73%)
377,824 int_misc.recovery_cycles (66.76%)
10,159 machine_clears.count (66.76%)
7,010,861,225 uops_executed.stall_cycles (66.65%)
7,993,995,420 resource_stalls.any (66.51%)
[rax+8]
的情况3:
6,810,946,768 cycles (66.69%)
1,641 ld_blocks_partial.address_alias (66.73%)
223,062 int_misc.recovery_cycles (66.73%)
7,349 machine_clears.count (66.74%)
3,618,236,557 uops_executed.stall_cycles (66.58%)
5,777,653,144 resource_stalls.any (66.53%)
[rax+32]
:
4,202,233,246 cycles (66.68%)
2,969 ld_blocks_partial.address_alias (66.68%)
149,308 int_misc.recovery_cycles (66.68%)
4,522 machine_clears.count (66.68%)
1,202,497,606 uops_executed.stall_cycles (66.64%)
3,179,044,737 resource_stalls.any (66.64%)
最佳答案
T1; DR:对于这三种情况,在同时执行加载和存储时会产生几个周期的损失。在这三种情况下,负载等待时间都位于关键路径上,但是在不同情况下,代价是不同的。由于额外的负载,情况3比情况1高出一个周期。
分析方法1:使用停顿性能事件
对于IvB和SnB的所有三种情况,我都能够重现您的结果。我得到的数字在您数字的2%以内。执行情况1、2和4的单次迭代所需的周期数分别是5.4、8.9和6.6。
让我们从前端开始。 LSD.CYCLES_4_UOPS
和LSD.CYCLES_3_UOPS
性能事件表明,基本上所有uops都是从LSD发出的。此外,这些事件与LSD.CYCLES_ACTIVE
一起显示,在LSD没有停止的每个周期中,情况1和2发出3 uops,情况3发出4 uops。换句话说,每个迭代在单个周期中在同一组中一起发布。
在以下所有关系中,“=〜”符号表示差异在2%以内。我将从以下经验观察开始:UOPS_ISSUED.STALL_CYCLES
+ LSD.CYCLES_ACTIVE
=〜cycles
请注意,如here中所述,需要调整SnB上的LSD事件计数。
我们还有以下关系:
情况1:UOPS_ISSUED.STALL_CYCLES
=〜RESOURCE_STALLS.ANY
=〜4.4c/iter
情况2:UOPS_ISSUED.STALL_CYCLES
=〜RESOURCE_STALLS.ANY
=〜7.9c/iter
情况3:UOPS_ISSUED.STALL_CYCLES
=〜RESOURCE_STALLS.ANY
=〜5.6c/iter
这意味着问题停滞的原因是因为后端中的一个或多个所需资源不可用。因此,我们可以放心地从考虑中消除整个前端。在情况1和2中,该资源是RS。在情况3中,由于RS造成的停顿约占所有资源停顿的20%1。
现在让我们集中讨论案例1。总共有4个未融合的域uops:1个负载uop,1个STA,1个STD和1个dec/jne。负载和STA负载取决于先前的负载。每当LSD发出一组uops时,就可以在下一个周期中调度STD和跳转uops,因此下一个周期不会导致执行停止事件。但是,可以分派(dispatch)负载和STA uops的最早时间是在将负载结果回写的同一周期中。 CYCLES_NO_EXECUTE
和STALLS_LDM_PENDING
之间的相关性表明,将没有准备就绪的uops的原因是因为RS中的所有uops都在等待L1为未决的负载请求提供服务。具体而言,RS中的微指令的一半是负载微指令,另一半是STA,它们都在等待相应的先前迭代的负载完成。 LSD.CYCLES_3_UOPS
显示LSD等待直到RS中至少有4个空闲条目,然后才发出一组构成完整迭代的uops。在下一个周期中,将分派(dispatch)其中的两个微指令,从而释放2个RS条目2。另一个将不得不等待它们所依赖的负载来完成。加载很可能按程序顺序完成。因此,LSD等待直到STA和尚未执行的最旧迭代的加载块离开RS。因此,UOPS_ISSUED.STALL_CYCLES
+1 =〜平均负载等待时间3。我们可以得出结论,情况1的平均负载延迟为5.4c。除了一个区别,大多数情况都适用于情况2,我将在稍后进行解释。
由于每次迭代中的微指令都形成一个依赖链,所以我们也有:cycles
=〜平均负载延迟。
因此:cycles
=〜UOPS_ISSUED.STALL_CYCLES
+ 1 =〜平均加载延迟。
在情况1中,平均负载延迟为5.4c。我们知道L1高速缓存的最佳情况延迟是4c,因此有1.4c的负载延迟损失。但是为什么有效负载延迟不是4c?
调度程序将预测uoop所依赖的负载将在某个恒定的延迟内完成,因此它将调度它们以进行相应的调度。如果由于某种原因(例如L1丢失)而使装载花费的时间超过了装载时间,则将派出uops,但装载结果尚未到达。在这种情况下,将重播这些微指令,并且已分配的微指令的数量将大于已发出的微指令的总数。
只能将load和STA uops调度到端口2或3。事件UOPS_EXECUTED_PORT.PORT_2
和UOPS_EXECUTED_PORT.PORT_3
可以分别用来计算分发到端口2和3的uops的数量。
情况1:UOPS_EXECUTED_PORT.PORT_2
+ UOPS_EXECUTED_PORT.PORT_3
=〜2uops/iter
情况2:UOPS_EXECUTED_PORT.PORT_2
+ UOPS_EXECUTED_PORT.PORT_3
=〜6uops/iter
情况3:UOPS_EXECUTED_PORT.PORT_2
+ UOPS_EXECUTED_PORT.PORT_3
=〜4.2uops/iter
在情况1中,已分配的AGU uops总数与已淘汰的AGU uops总数完全相同;没有重播。因此,调度程序永远不会出错。在情况2中,每个AGU uop平均有2个重播,这意味着调度程序平均每个AGU uop有两次错误的预测。为什么在情况2中有错误的预测,而在情况1中却没有?
出于以下任何原因,调度程序将根据负载重播uops:
Lastly yes, there are 'a few' idle cycles when switching between a load and a store. I'm told not to be more specific than 'a few'.
...
SNB can read and write different banks at the same cycle.
CYCLE_ACTIVITY.STALLS_LDM_PENDING
估算每个操作的贡献。执行STA uop需要一个周期,因此商店可以在紧跟STA派发STA的周期之后退出。
CYCLE_ACTIVITY.STALLS_LDM_PENDING
+ 1个周期(分配负载的周期)+1个周期(分配跳转uop的周期)。我们需要在
CYCLE_ACTIVITY.STALLS_LDM_PENDING
中添加2个周期,因为这些周期中没有执行停顿,但它们仅占总加载延迟的一小部分。这等于6.8 + 2 = 8.8个周期=〜
cycles
。
T
+0。我将把该加载uop所属的迭代称为当前迭代。将发生以下事件序列:
T
+ 0周期:调度当前迭代的STA uop和下一个迭代的load uop。此周期中没有分配,因为没有足够的RS条目。该周期被计为分配停顿周期,而不是执行停顿周期。
T
+ 1循环中:STA uop完成执行,并且存储退出。分配要分配的下一个迭代的微指令。该周期被计为执行停顿周期,而不是分配停顿周期。
T
+ 2周期中:刚刚分配的跳转和STD指令被调度。该周期被计为分配停顿周期,而不是执行停顿周期。
T
+ 3到
T
+ 3 +
CYCLE_ACTIVITY.STALLS_LDM_PENDING
-2周期中:所有这些周期都被计为执行和分配停顿周期。请注意,这里有
CYCLE_ACTIVITY.STALLS_LDM_PENDING
-1个周期。
UOPS_ISSUED.STALL_CYCLES
应该等于1 + 0 + 1 +
CYCLE_ACTIVITY.STALLS_LDM_PENDING
-1。让我们检查一下:7.9 = 1 + 0 + 1 + 6.8-1。
cycles
应该等于
UOPS_ISSUED.STALL_CYCLES
+ 1 = 7.9 + 1 =〜实际测得的
cycles
。同时执行加载和存储操作时的损失比情况1高3.6c。这似乎是加载正在等待存储被提交时的损失。我认为这也可以解释为什么在情况2中有重放,但在情况1中没有重放。
UOPS_ISSUED.STALL_CYCLES
+ 1-1 =
UOPS_ISSUED.STALL_CYCLES
=〜平均负载延迟=〜5.6c,这与情况1的情况非常接近。 1.6c。这就解释了为什么在情况3中,与情况1和2相比,每个AGU uop平均要被调度1.4次。
cycles
=〜平均负载延迟+ 1 = 6.6c/iter,实际上与我系统上测得的
cycles
完全匹配。
MEM_TRANS_RETIRED.LOAD_LATENCY_*
性能事件。这些事件是特殊的,因为它们只能在
p Recise级别上计数(请参阅:
PERF STAT does not count memory-loads but counts memory-stores)。
MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4
计算延迟大于所有执行的负载的“随机”选择样本的4个核心周期的负载数。延迟的测量如下。第一次分配负载的周期是被认为是负载等待时间一部分的第一个周期。回写加载结果的周期是被视为等待时间一部分的最后一个周期。因此,考虑了重播。此外,根据此定义,至少从SnB开始,所有负载的延迟都大于4个周期。当前支持的最小等待时间阈值是3个周期。
Case 1
Lat Threshold | Sample Count
3 | 1426934
4 | 1505684
5 | 1439650
6 | 1032657 << Drop 1
7 | 47543 << Drop 2
8 | 57681
9 | 60803
10 | 76655
11 | <10 << Drop 3
Case 2
Lat Threshold | Sample Count
3 | 1532028
4 | 1536547
5 | 1550828
6 | 1541661
7 | 1536371
8 | 1537337
9 | 1538440
10 | 1531577
11 | <10 << Drop
Case 3
Lat Threshold | Sample Count
3 | 2936547
4 | 2890162
5 | 2921158
6 | 2468704 << Drop 1
7 | 1242425 << Drop 2
8 | 1238254
9 | 1249995
10 | 1240548
11 | <10 << Drop 3
MEM_TRANS_RETIRED.LOAD_LATENCY_*
进行测量很容易,并且这种分析可以由对微体系结构了解很少的人来完成。
关于assembly - 在IvyBridge上的指针追逐循环中,附近的从属存储产生了奇怪的性能影响。添加额外的负载可以加快速度吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54084992/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!