这个问题继续我的问题(根据神秘主义者的建议):
C代码循环性能
继续我的问题,当我使用压缩指令而不是标量指令时,使用内部函数的代码看起来非常相似:
for(int i=0; i<size; i+=16) {
y1 = _mm_load_ps(output[i]);
…
y4 = _mm_load_ps(output[i+12]);
for(k=0; k<ksize; k++){
for(l=0; l<ksize; l++){
w = _mm_set_ps1(weight[i+k+l]);
x1 = _mm_load_ps(input[i+k+l]);
y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
…
x4 = _mm_load_ps(input[i+k+l+12]);
y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
}
}
_mm_store_ps(&output[i],y1);
…
_mm_store_ps(&output[i+12],y4);
}
该内核的测量性能约为每个周期5.6个FP操作,尽管我预计它的性能恰好是标量版本的4倍,即每个周期4.1,6=6,4个FP操作。
考虑到权重因素的变动(感谢您指出),时间表如下所示:
虽然在movss操作之后有一条额外的指令将标量权重值移动到XMM寄存器,然后使用shufps在整个向量中复制该标量值,但调度似乎没有改变。考虑到从加载到浮点域的切换延迟,权重向量似乎可以及时用于mulp,因此这不应该产生任何额外的延迟。
移动APS(对齐、压缩移动),addps
有人知道每8个周期的额外周期花在哪里吗,假设这个内核可以获得的最大性能是每个周期6.4个FP op,并且它以每个周期5.6个FP op的速度运行?
顺便说一下,这里是实际组装的样子:
…
Block x:
movapsx (%rax,%rcx,4), %xmm0
movapsx 0x10(%rax,%rcx,4), %xmm1
movapsx 0x20(%rax,%rcx,4), %xmm2
movapsx 0x30(%rax,%rcx,4), %xmm3
movssl (%rdx,%rcx,4), %xmm4
inc %rcx
shufps $0x0, %xmm4, %xmm4 {fill weight vector}
cmp $0x32, %rcx
mulps %xmm4, %xmm0
mulps %xmm4, %xmm1
mulps %xmm4, %xmm2
mulps %xmm3, %xmm4
addps %xmm0, %xmm5
addps %xmm1, %xmm6
addps %xmm2, %xmm7
addps %xmm4, %xmm8
jl 0x401ad6 <Block x>
…
尝试在Vtune中使用EMON评测,或使用类似于oprof的工具
EMON(事件监控)分析=
要使用EMON分析,您必须遍历事件列表,从“通常的嫌疑人”到...
这里,我将从缓存未命中、对齐开始。我不知道您使用的处理器是否有一个射频端口限制计数器-它应该有-但我早就添加了EMON评测,我不知道他们通过添加适合微体系结构的事件来跟上进度。
也可能是前端、指令提取、暂停。这些指令中有多少字节?这方面也有EMON活动。
回应Nehalem VTune看不到三级事件的评论:不正确。以下是我在评论中添加的内容,但不合适:
实际上,对于LL3/L3$/所谓的Uncore,有一些性能计数器。如果VTune不支持它们,我会非常惊讶。看见http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf指向VTune和PTU等其他工具。事实上,即使没有LL3事件,正如David Levinthal所说:“Intel®Core™ i7处理器有一个“延迟事件”,与安腾处理器系列数据EAR事件非常相似。此事件对加载进行采样,记录指令执行与数据实际传递之间的周期数。如果测得的延迟大于MSR 0x3f6中编程的最小延迟(位15:0),则计数器将递增。计数器溢出启用PEBS机制,在下一个满足延迟阈值的事件中,测量的延迟、虚拟或线性地址和数据源被复制到PEBS缓冲区中的3个附加寄存器中。由于虚拟地址被捕获到已知位置,因此采样驱动程序还可以执行虚拟到物理的转换并捕获物理地址。物理地址标识NUMA主位置,原则上允许分析缓存占用的详细信息。“他还在第35页指出了VTune事件,如L3 CACHE\u HIT\u UNCORE\u HIT和L3 CACHE\u MISS\u REMOTE\DRAM。有时您需要查找数字代码并将其编程到VTune的低级界面中,但我认为在这种情况下,它在漂亮的用户界面中是可见的。
好的,在http://software.intel.com/en-us/forums/showthread.php?t=77700
他错了——例如,您可以只启用一个CPU,并进行有意义的采样。我还相信,当L3返回CPU时,它能够标记丢失的数据。事实上,总体而言,L3知道它将数据返回到哪个CPU,因此您可以明确地进行采样。您可能不知道哪个超线程,但可以再次禁用,进入单线程模式。
但看起来,这是相当普遍的,你必须围绕VTune工作,而不是使用它,才能做到这一点。
首先尝试延迟分析。这完全在CPU内部,VTune人员不太可能把它搞得太糟。
我再说一遍,很可能你的问题出在核心,而不是L3。所以VTune应该能够处理这个问题。
按照Levinthal的说法试试“循环会计”。
问题内容: 我在评估我的Java代码时遇到了一个大问题。为了简化问题,我编写了以下代码,它们产生相同的奇怪行为。重要的是方法run()和给定的双倍价值率。对于运行时测试(在main方法中),我将速率设置为0.5倍,另一次设置为1.0。如果值为1.0,则将在每次循环迭代中执行if语句;如果值为0.5,则将执行一半的if语句。因此,在第一种情况下,我希望运行时更长,但事实恰恰相反。谁能解释这个现象?
我在写一段代码,其中有一个字符串[]和一个方法,该方法接受这个字符串[]并返回字节[],保持字符串-字节对的位置,其中很少有字节可以为空。最后,我必须对字节进行转换,并从string[]中获取一个键为string,值为转换返回值的映射。这就是我在Java 8流中实现相同功能的方式: 其中productReference是字符串[],ProductSpice[]是字节[]数组。 现在的问题是IntS
有的时候,可能需要多次执行同一块代码。一般情况下,语句是顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。 编程语言提供了允许更为复杂的执行路径的多种控制结构。 循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的一般形式: 循环类型 C++ 编程语言提供了以下几种循环类型。点击链接查看每个类型的细节。 循环类型 描述 while 循环 当给定条件为真时,重复
问题内容: 当我的研究使我相信循环是PHP中最快的迭代构造…为了使它更清晰时,您认为以下哪个会更快? 示例一 示例二 我的逻辑是,在示例中的每次迭代中,在每次迭代中访问myLargeArray的长度比在示例二中访问简单的整数值要昂贵。那是对的吗? 问题答案: 第一种方法较慢,因为必须在循环的每次迭代中都调用该函数。该方法本身非常快,但是调用该函数仍然有一些开销。通过将其移动到循环之外,您正在执行所
问题内容: 与使用C ++或C相比,使用Java进行编程变得越来越舒适。我希望能感觉到使用JVM解释器引起的性能下降,而不是本地执行相同的“项目”。我意识到这里有一定程度的主观性。程序的质量将在很大程度上取决于良好的实施。我对一般意义上的以下方面感兴趣: 使用解释器时,必须有一些开销基线。有一些一般的经验法则要记住吗?10%15%?(我凭空想出了这些数字)我读过偶尔的博客,指出Java代码几乎与本
主要内容:1. 循环控制语句,2. 无限循环当需要多次执行同一代码块时,可以使用循环来解决。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。 编程语言提供各种控制结构,允许更复杂的执行路径。循环语句可用于多次执行语句或语句组,以下是大多数编程语言中循环语句的一般形式 - Objective-C编程语言提供以下类型的循环来处理循环需求。单击以下相应链接来查看其详细信息。 编号 循环类型 描述 1 while循