在这个简单的示例中,我对使用有符号循环计数器和无符号循环计数器之间的差异感到非常惊讶:
double const* a;
__assume_aligned(a, 64);
double s = 0.0;
//for ( unsigned int i = 0; i < 1024*1024; i++ )
for ( int i = 0; i < 1024*1024; i++ )
{
s += a[i];
}
Run Code Online (Sandbox Code Playgroud)
在签名的情况下,生成了 icc 19.0.0(我显示了循环的展开部分):
..B1.2:
vaddpd zmm7, zmm7, ZMMWORD PTR [rdi+rax*8]
vaddpd zmm6, zmm6, ZMMWORD PTR [64+rdi+rax*8]
vaddpd zmm5, zmm5, ZMMWORD PTR [128+rdi+rax*8]
vaddpd zmm4, zmm4, ZMMWORD PTR [192+rdi+rax*8]
vaddpd zmm3, zmm3, ZMMWORD PTR [256+rdi+rax*8]
vaddpd zmm2, zmm2, ZMMWORD PTR [320+rdi+rax*8]
vaddpd zmm1, …Run Code Online (Sandbox Code Playgroud) optimization assembly icc compiler-optimization unsigned-integer
我正在尝试为内存限制的矢量化循环确定性能基线.我是在具有AVX2指令的Intel Broadwell芯片上在32字节对齐环境中执行此操作.
基线循环一次使用8个YMM寄存器从一个位置加载并且非时间存储到另一个位置:
%define ptr
%define ymmword yword
%define SIZE 16777216*8 ;; array size >> LLC
align 32 ;; avx2 vector alignement
global _ls_01_opt
section .text
_ls_01_opt: ;rdi is input, rsi output
push rbp
mov rbp,rsp
xor rax,rax
mov ebx, 111 ; IACA PREFIX
db 0x64, 0x67, 0x90 ;
LOOP0:
vmovapd ymm0, ymmword ptr [ (32) + rdi +8*rax]
vmovapd ymm2, ymmword ptr [ (64) + rdi +8*rax]
vmovapd ymm4, ymmword ptr [ (96) + rdi +8*rax]
vmovapd ymm6, ymmword …Run Code Online (Sandbox Code Playgroud) 在编码时我遇到了一个问题:
当我必须使用大量for循环时,所有迭代都在不同的范围内.如果我只将一个变量声明为索引(示例I)或者它根本不重要(示例II),那么性能(即运行时)会更好吗?
例I:
int ind;
for(ind=0; ind < a; ind++) { /*do something*/ }
for(ind=0; ind < b; ind++) { /*to something*/ }
...
for(ind=0; ind < z; ind++) { /*to something*/ }
Run Code Online (Sandbox Code Playgroud)
例二:
for(int ind=0; ind < a; ind++) { /*do something*/ }
...
for(int ind=0; ind < z; ind++) { /*do something*/ }
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助
I have implemented a program for a[i]=a[i-1]+c and I represent it her. I use begin_rdtsc and end_rdtsc to read and store the rdtsc to measure the speedup.
The program is as follows, I use x86intrin.h
#define MAX1 512
#define LEN MAX1*MAX1 //array size for time measure ments
int __attribute__(( aligned(32))) a[LEN];
int main(){
singleCore // It's a macro to assign the program to a single core of the processor
int i, b, c;
begin_rdtsc
// b=1 and c=2 in this …Run Code Online (Sandbox Code Playgroud) 该程序(来自 Jonathan Bartlett 的《从头开始编程》)循环访问内存中存储的所有数字,并将.long最大的数字放入 EBX 寄存器中,以便在程序完成时查看。
.section .data
data_items:
.long 3, 67, 34, 222, 45, 75, 54, 34, 44, 33, 22, 11, 66, 0
.section .text
.globl _start
_start:
movl $0, %edi
movl data_items (,%edi,4), %eax
movl %eax, %ebx
start_loop:
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items (,%edi,4), %eax
cmpl %ebx, %eax
jle start_loop
movl %eax, %ebx
jmp start_loop
loop_exit:
movl $1, %eax
int $0x80
Run Code Online (Sandbox Code Playgroud)
我不确定(,%edi,4)这个程序的目的。我读到逗号是为了分隔,而 4 是为了提醒我们的计算机数据项中的每个数字都是 4 个字节长。既然我们已经用.long声明了每个数字都是4个字节,为什么我们还需要在这里再声明一次呢?另外,有人可以更详细地解释这两个逗号在这种情况下的用途吗?
我想用AVX2指令加快以下操作,但我无法找到一种方法.
我得到了uint64_t data[100000]一大堆uint64_t和一个unsigned char indices[100000]字节数组.我想输出一个数组uint64_t Out[256],其中第i个值是所有data[j]这样的xor index[j]=i.
我想要的直接实现是这样的:
uint64_t Out[256] = {0}; // initialize output array
for (i = 0; i < 100000 ; i++) {
Out[Indices[i]] ^= data[i];
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用AVX2指令更有效地实现这一点吗?
编辑:这是我的代码现在的样子
uint64_t Out[256][4] = {0}; // initialize output array
for (i = 0; i < 100000 ; i+=4) {
Out[Indices[i ]][0] ^= data[i];
Out[Indices[i+1]][1] ^= data[i+1];
Out[Indices[i+2]][2] ^= data[i+2];
Out[Indices[i+3]][3] ^= data[i+3];
}
Run Code Online (Sandbox Code Playgroud) 我的印象是,在查看u-op缓存一段时间后,每个微操作都是8个字节,但我的问题是所有微操作都是相同的大小,甚至是融合域微操作?
在“Intel CPU 中的 MicroFusion”中。丹尼斯·巴赫瓦洛夫 (Denis Bakhvalov)说道:
\n
\nSandyBridge 的取消层压在《Intel\xc2\xae 64 和 IA-32 架构优化参考手册》章节 \xe2\x80\x9c2.3.2.4:微操作队列和循环流检测器 (LSD)\xe2\x80 中进行了描述\x9d:
\n\n微操作队列为某些指令类型提供解码后功能。特别是,与计算操作和所有存储相结合的加载,当与索引寻址一起使用时,在解码器或解码 ICache 中表示为单个微操作。在微操作队列中,它们通过称为取消分层的过程被分成两个微操作,一个执行加载,另一个执行操作
\n
BeeOnRope在HackerNews 主题中指出:
\n\n\n当指令在解码时融合,但在重命名之前为 \xe2\x80\x9cunlaminate\xe2\x80\x9d 时,它通常具有与根本不融合相似的性能(但它确实节省了 uop 缓存中的空间),因为 RAT 更可能是性能限制。
\n
在这种情况下,为什么在指令解码时使用unlamination而不是使用更多 \xce\xbcops使用更多的 \xce\xbcops ?看起来没有必要吗?
\n还是因为给定的\xce\xbcop是否应该unlamination在解码阶段是不确定的,需要根据运行时的CPU使用情况动态确定?
\n这是我的代码汇编程序
你能用c ++嵌入它并检查SSE4吗?速度快
我非常希望看到如何进入SSE4的发展.或者根本不担心他?我们检查一下(我没有SSSE3以上的支持)
{ sse2 strcmp WideChar 32 bit }
function CmpSee2(const P1, P2: Pointer; len: Integer): Boolean;
asm
push ebx // Create ebx
cmp EAX, EDX // Str = Str2
je @@true // to exit true
test eax, eax // not Str
je @@false // to exit false
test edx, edx // not Str2
je @@false // to exit false
sub edx, eax // Str2 := Str2 - Str;
mov ebx, [eax] // get Str 4 byte
xor …Run Code Online (Sandbox Code Playgroud) 如果编译器将高级语言转换为机器代码,为什么我们甚至需要汇编程序呢?是否有任何汇编级语言,我们不能使用编译器?