相关疑难解决方法(0)

在x86汇编中将寄存器设置为零的最佳方法是什么:xor,mov或?

以下所有说明都做同样的事情:设置%eax为零.哪种方式最佳(需要最少的机器周期)?

xorl   %eax, %eax
mov    $0, %eax
andl   $0, %eax
Run Code Online (Sandbox Code Playgroud)

optimization performance x86 assembly micro-optimization

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

微融合和寻址模式

我使用英特尔®架构代码分析器(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
查看次数

在现代(流水线/超标量)处理器上执行x86 rep指令

我最近一直在写x86程序集(为了好玩),并且想知道rep前缀字符串指令是否实际上在现代处理器上具有性能优势,或者它们是否刚刚实现了后向兼容性.

我理解为什么当处理器一次只运行一条指令时,英特尔最初会实现代表指令,但现在使用它们有什么好处?

通过循环可以编译更多指令,还有更多要填充管道和/或无序发布.现代处理器是为优化这些重复前缀指令而构建的,还是在现代代码中很少使用的rep指令,它们对制造商来说并不重要?

performance x86 assembly pipeline

18
推荐指数
2
解决办法
7923
查看次数

如果可用,gcc是否使用英特尔的SSE 4.2指令进行文本处理?

在这里读到英特尔SSE 4.2 instructions为加速字符串处理而推出的.

从文章引用:

SSE 4.2指令集首先在Intel的Core i7中实现,提供了字符串和文本处理指令(STTNI),它们利用SIMD操作处理字符数据.虽然最初设想用于加速字符串,文本和XML处理,但这些指令的强大新功能在这些域之外是有用的,值得重新审视众多应用程序的搜索和识别阶段,以利用STTNI来提高性能

  • gcc是否可以使用这些说明?
  • 如果是这样,哪个版本?
  • 如果没有,是否有任何开源库提供此功能?

c c++ gcc sse simd

10
推荐指数
1
解决办法
4071
查看次数

使用未对齐缓冲区进行矢量化:使用VMASKMOVPS:根据未对齐计数生成掩码?或者根本不使用那个insn

gcc 5.3 with -O3 -mavx -mtune=haswellfor x86-64使得代码处理可能错位的代码变得非常笨重,例如:

// convenient simple example of compiler input
// I'm not actually interested in this for any real program
void floatmul(float *a) {
  for (int i=0; i<1024 ; i++)
    a[i] *= 2;
}
Run Code Online (Sandbox Code Playgroud)

clang使用未对齐的加载/存储指令,但是gcc执行标量intro/outro和对齐的向量循环:它剥离了第一个最多7个未对齐的迭代,将其完全展开为一个序列

    vmovss  xmm0, DWORD PTR [rdi]
    vaddss  xmm0, xmm0, xmm0      ; multiply by two
    vmovss  DWORD PTR [rdi], xmm0
    cmp     eax, 1
    je      .L13
    vmovss  xmm0, DWORD PTR [rdi+4]
    vaddss  xmm0, xmm0, xmm0
    vmovss …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc sse avx

10
推荐指数
2
解决办法
960
查看次数

我可以使用 SIMD 来加速字符串操作吗?

SIMD 指令是否仅用于矢量数值计算?或者它是否适合一类字符串操作任务,例如将数据行写入文本文件,其中行的顺序无关紧要?如果是这样,我应该从哪些 API 或库开始?

c c++ string optimization simd

8
推荐指数
3
解决办法
672
查看次数

SSE42和STTNI - PcmpEstrM比PcmpIstrM慢两倍,是真的吗?

我正在尝试使用SSE42和STTNI指令并得到奇怪的结果 - PcmpEstrM(使用显式长度字符串)比PcmpIstrM(隐式长度字符串)运行慢两倍.

  • 在我的i7 3610QM上,差异是2366.2毫秒,而1202.3毫秒 - 97%.
  • i5 3470上差异不是那么大,但仍然显着= 3206.2毫秒与2623.2毫秒--22%.

两者都是"常春藤桥" - 奇怪的是他们有如此不同的"差异"(至少我看不出他们的规格有任何技术差异 - http://www.cpu-world.com/Compare_CPUs/Intel_AW8063801013511,Intel_CM8063701093302 /).

英特尔64和IA-32架构优化参考手册提到了PcmpEstrM和PcmpIstrM的相同吞吐量= 11和延迟= 3.因此,我预计两者的表现相似.

问:差异是我实际设计/预期的,还是我以错误的方式使用这些指令?

下面是我的虚拟测试场景(VS 2012).逻辑非常简单 - 扫描16MB文本以查找匹配字符.由于干草堆和针头串都没有包含零终结器 - 我希望E和I具有相似的性能.

PS:我尝试在intel的开发论坛上发布这个问题,但他们将其识别为垃圾邮件:(

#include "stdafx.h"
#include <windows.h>
#define BEGIN_TIMER(NAME)                       \
    {                                           \
        LARGE_INTEGER   __freq;                 \
        LARGE_INTEGER   __t0;                   \
        LARGE_INTEGER   __t1;                   \
        double          __tms;                  \
        const char*     __tname = NAME;         \
        char            __tbuf[0xff];           \
        \
        QueryPerformanceFrequency(&__freq);     \
        QueryPerformanceCounter(&__t0);         
#define END_TIMER()                             \ …
Run Code Online (Sandbox Code Playgroud)

c++ performance sse sse4

7
推荐指数
1
解决办法
822
查看次数

为什么 SSE4.2 cmpstr 比常规代码慢?

我正在尝试验证一个只能包含 ASCII 可见字符、空格和 \t 的字符串。

但在大多数 CPU 上,ASCII 表查找似乎比带有 _SIDD_CMP_RANGES 的 _mm_cmpestri 指令更快。我已经在 i5-2410M、i7-3720QM、i7-5600U 和未知类型的 KVM 虚拟化 Xeon 上进行了测试,只有最后一个矢量化版本速度更快。

我的测试代码在这里:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <immintrin.h>
#include <stdalign.h>
#include <stdlib.h>

#define MIN(a,b) (((a)<(b))?(a):(b))

#define ALIGNED16 alignas(16)

#define MEASURE(msg,stmt) { \
    struct timeval tv; \
    gettimeofday(&tv, NULL); \
    uint64_t us1 = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec; \
    stmt; \
    gettimeofday(&tv, NULL); \
    uint64_t us2 = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec; \
    printf("%-20s - %.4fms\n", msg, …
Run Code Online (Sandbox Code Playgroud)

c performance x86 assembly sse

5
推荐指数
1
解决办法
1003
查看次数

“if consteval”提案文件中的“SSE 4.2 insanity”是什么意思?

我正在阅读一篇关于if consteval (\xc2\xa73.2)的 C++ 论文,并看到一段显示constexpr strlen实现的代码:

\n
constexpr size_t strlen(char const* s) {\n    if constexpr (std::is_constant_evaluated()) {\n        for (const char *p = s; ; ++p) {\n            if (*p == \'\\0\') {\n                return static_cast<std::size_t>(p - s);\n            }\n        }    \n    } else {\n        __asm__("SSE 4.2 insanity");        \n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我是来询问__asm__else分支中的语句的。

\n

我知道这是幽默,并不意味着要认真对待,但我仍然决定做一些研究,以防有人已经解释过。\n当我用谷歌搜索引用的消息时,我得到的结果不到 10 个,全部都是关于这段代码的.\n然后我研究了什么是SSE 4.2,发现它是一个CPU指令集,所以我真的不知道它在C++论文中出现的内容,有人有解释吗?\n感谢那些会阅读的人我的帖子。

\n

c++ sse sse4 c++23

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

标签 统计

assembly ×5

sse ×5

x86 ×5

c++ ×4

performance ×4

c ×3

gcc ×2

optimization ×2

simd ×2

sse4 ×2

avx ×1

c++23 ×1

cpu ×1

iaca ×1

intel ×1

micro-optimization ×1

pipeline ×1

string ×1