相关疑难解决方法(0)

有符号或无符号循环计数器

在这个简单的示例中,我对使用有符号循环计数器和无符号循环计数器之间的差异感到非常惊讶:

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

4
推荐指数
1
解决办法
1184
查看次数

用于AVX加载/存储指令的Intel broadwell uop fusion

我正在尝试为内存限制的矢量化循环确定性能基线.我是在具有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)

assembly intel avx avx2 iaca

3
推荐指数
1
解决办法
301
查看次数

具有相同索引的for循环的性能

在编码时我遇到了一个问题:

当我必须使用大量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)

谢谢您的帮助

c c++ indexing performance for-loop

3
推荐指数
1
解决办法
192
查看次数

What is the reason for different performance of the same implementation using icc, gcc and clang?

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)

x86 assembly gcc simd icc

3
推荐指数
1
解决办法
280
查看次数

汇编:这个程序中movl data_items(,%edi,4), %eax的作用是什么

该程序(来自 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个字节,为什么我们还需要在这里再声明一次呢?另外,有人可以更详细地解释这两个逗号在这种情况下的用途吗?

x86 assembly att addressing-mode array-indexing

3
推荐指数
1
解决办法
1864
查看次数

选择性地使用AVX2指令对列表中的元素进行排序

我想用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)

optimization x86 simd avx avx2

3
推荐指数
1
解决办法
226
查看次数

在现代x86 CPU中,所有微操作都是相同的长度吗?

我的印象是,在查看u-op缓存一段时间后,每个微操作都是8个字节,但我的问题是所有微操作都是相同的大小,甚至是融合域微操作?

x86 cpu-architecture instructions

3
推荐指数
1
解决办法
115
查看次数

为什么需要取消层压?

“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
\n

BeeOnRope在HackerNews 主题中指出:

\n
\n

当指令在解码时融合,但在重命名之前为 \xe2\x80\x9cunlaminate\xe2\x80\x9d 时,它通常具有与根本不融合相似的性能(但它确实节省了 uop 缓存中的空间),因为 RAT 更可能是性能限制。

\n
\n

在这种情况下,为什么在指令解码时使用unlamination而不是使用更多 \xce\xbcops使用更多的 \xce\xbcops ?看起来没有必要吗?

\n

还是因为给定的\xce\xbcop是否应该unlamination在解码阶段是不确定的,需要根据运行时的CPU使用情况动态确定?

\n

cpu x86 intel cpu-architecture

3
推荐指数
1
解决办法
179
查看次数

对于memcmp,SSE4.2字符串指令比SSE2快多少?

这是我的代码汇编程序

你能用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)

x86 assembly sse micro-optimization sse4

2
推荐指数
1
解决办法
1374
查看次数

为什么在编译时我们甚至需要汇编程序?

如果编译器将高级语言转换为机器代码,为什么我们甚至需要汇编程序呢?是否有任何汇编级语言,我们不能使用编译器?

compiler-construction assembly compiler-optimization

2
推荐指数
1
解决办法
638
查看次数