相关疑难解决方法(0)

什么是IACA以及如何使用它?

我发现了这个有趣且功能强大的工具IACA(英特尔架构代码分析器),但我无法理解它.我能用它做什么,它的局限性是什么?我该怎么做:

  • 用它来分析C或C++中的代码?
  • 用它来分析x86汇编程序中的代码?

c c++ performance assembly iaca

54
推荐指数
1
解决办法
7985
查看次数

微融合和寻址模式

我使用英特尔®架构代码分析器(IACA)发现了一些意想不到的东西(对我而言).

以下指令使用[base+index]寻址

addps xmm1, xmmword ptr [rsi+rax*1]
Run Code Online (Sandbox Code Playgroud)

根据IACA没有微熔丝.但是,如果我用[base+offset]这样的

addps xmm1, xmmword ptr [rsi]
Run Code Online (Sandbox Code Playgroud)

IACA报告它确实融合了.

英特尔优化参考手册的第2-11节给出了以下"可以由所有解码器处理的微融合微操作"的示例

FADD DOUBLE PTR [RDI + RSI*8]
Run Code Online (Sandbox Code Playgroud)

Agner Fog的优化装配手册也给出了使用[base+index]寻址的微操作融合的例子.例如,请参见第12.2节"Core2上的相同示例".那么正确的答案是什么?

cpu x86 assembly intel iaca

44
推荐指数
4
解决办法
4504
查看次数

如果没有Skylake上的VZEROUPPER,为什么这个SSE代码会慢6倍?

我一直试图找出应用程序中的性能问题,并最终将其缩小到一个非常奇怪的问题.如果VZEROUPPER指令被注释掉,则下面的代码在Skylake CPU(i5-6500)上运行速度慢6倍.我测试了Sandy Bridge和Ivy Bridge CPU,两种版本都以相同的速度运行,有或没有VZEROUPPER.

现在我VZEROUPPER对这个代码有了一个相当好的想法,而且我认为当没有VEX编码指令并且没有调用可能包含它们的任何函数时,它对这个代码根本不重要.事实上它不支持其他支持AVX的CPU似乎支持这一点.英特尔®64和IA-32架构优化参考手册中的表11-2也是如此

那么发生了什么?

我留下的唯一理论是,CPU中存在一个错误,它错误地触发了"保存AVX寄存器的上半部分"程序,而不应该这样做.或者其他一些同样奇怪的东西.

这是main.cpp:

#include <immintrin.h>

int slow_function( double i_a, double i_b, double i_c );

int main()
{
    /* DAZ and FTZ, does not change anything here. */
    _mm_setcsr( _mm_getcsr() | 0x8040 );

    /* This instruction fixes performance. */
    __asm__ __volatile__ ( "vzeroupper" : : : );

    int r = 0;
    for( unsigned j = 0; j < 100000000; ++j )
    {
        r |= slow_function( 
                0.84445079384884236262,
                -6.1000481519580951328, …
Run Code Online (Sandbox Code Playgroud)

performance x86 sse intel avx

32
推荐指数
2
解决办法
4072
查看次数

AVX2中冲突检测的后备实现

AVX512CD包含内部函数,_mm512_conflict_epi32(__m512i a)它返回一个向量,a如果它具有相同的值,则为其中的每个元素设置.有没有办法在AVX2中做类似的事情?

我对extact位不感兴趣,我只需要知道哪些元素是左侧(或右侧)元素的重复.我只需要知道分散是否会发生冲突.

基本上我需要一个AVX2等价物

__mm256i detect_conflict(__mm256i a) {
  __mm256i cd = _mm256_conflict_epi32(a);
  return _mm256_cmpgt_epi32(cd, _mm256_set1_epi32(0));
}
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一方法是使用_mm256_permutevar8x32_epi32()将每个值向右移动1(跨越通道),然后进行七次比较,屏蔽掉未经过的位,而不是将_mm256_or_si256()它们放在一起,这是非常慢的.

c++ x86 intrinsics avx2 avx512

11
推荐指数
1
解决办法
429
查看次数

选择性地使用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
查看次数

从GP regs加载xmm

假设你有值rax,rdx你想加载到xmm寄存器中.

一种方法是:

movq     xmm0, rax
pinsrq   xmm0, rdx, 1
Run Code Online (Sandbox Code Playgroud)

虽然这很慢!有没有更好的办法?

x86 assembly sse simd micro-optimization

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

标签 统计

x86 ×5

assembly ×3

avx ×2

avx2 ×2

c++ ×2

iaca ×2

intel ×2

performance ×2

simd ×2

sse ×2

avx512 ×1

c ×1

cpu ×1

intrinsics ×1

micro-optimization ×1

optimization ×1