相关疑难解决方法(0)

在运行中生成矢量常数的最佳指令序列是什么?

"最佳"意味着最少的指令(或最少的uops,如果任何指令解码到多个uop).机器码大小(以字节为单位)是相同insn计数的平局.

恒定生成本质上是一个新的依赖链的开始,所以延迟很重要.在循环内生成常量也很不寻常,因此吞吐量和执行端口需求也几乎无关紧要.

生成常量而不是加载它们需要更多指令(除了全零或全一),因此它会占用宝贵的uop-cache空间.这可能是比数据缓存更有限的资源.

Agner Fog优秀的优化装配指南涵盖了这一点Section 13.4.表13.10具有用于产生向量序列,每一个元素是0,1,2,3,4,-1,或-2,与从8位到64位单元大小.表13.11具有用于产生一些浮点值序列(0.0,0.5,1.0,1.5,2.0,-2.0,和位掩码为符号位.)

Agner Fog的序列仅使用SSE2,无论是设计还是因为它尚未更新一段时间.

使用短的非显而易见的指令序列可以生成哪些其他常量? (具有不同移位计数的进一步扩展是显而易见的而不是"有趣的".)是否有更好的序列用于生成Agner Fog列出的常量?

如何将128位immediates移动到XMM寄存器说明了将任意128b常量放入指令流的一些方法,但这通常是不合理的(它不会节省任何空间,并占用大量的uop-cache空间.)

x86 assembly sse simd avx

24
推荐指数
1
解决办法
1733
查看次数

使用SIMD持续浮动

我一直在尝试使用microsoft的sse内在函数来优化我使用的代码.优化我的代码时最大的问题之一是每当我想使用常量时就会发生LHS.似乎有一些关于生成某些常量的信息(这里这里 - 第13.4节),但它的所有汇编(我宁愿避免).

问题是当我尝试用内在函数实现相同的东西时,msvc抱怨不兼容的类型等.有没有人知道使用内在函数的任何等效技巧?

示例 - 生成{1.0,1.0,1.0,1.0}

//pcmpeqw xmm0,xmm0 
__m128 t = _mm_cmpeq_epi16( t, t );

//pslld xmm0,25 
_mm_slli_epi32(t, 25);

//psrld xmm0,2
return _mm_srli_epi32(t, 2);
Run Code Online (Sandbox Code Playgroud)

这会产生一堆关于不兼容类型的错误(__m128 vs _m128i).我对此很陌生,所以我很确定我错过了一些明显的东西.有人可以帮忙吗?

tldr - 如何使用ms intrinsics生成一个填充了单精度常量浮点数的__m128 vec?

谢谢阅读 :)

c++ optimization sse simd

7
推荐指数
2
解决办法
995
查看次数

_mm_broadcast_ss比_mm_set1_ps快吗?

这是代码

float a = ...;
__m256 b = _mm_broadcast_ss(&a)
Run Code Online (Sandbox Code Playgroud)

总是比这段代码快

float a = ...;
_mm_set1_ps(a)
Run Code Online (Sandbox Code Playgroud)

如果a被定义为static const float a = ...而不是float a = ...

vectorization avx

6
推荐指数
3
解决办法
4824
查看次数

标签 统计

avx ×2

simd ×2

sse ×2

assembly ×1

c++ ×1

optimization ×1

vectorization ×1

x86 ×1