相关疑难解决方法(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万
查看次数

SSE入门

我想了解有关使用SSE的更多信息.

除了明显阅读英特尔®64和IA-32架构软件开发人员手册之外,还有哪些方法可以学习?

主要是我有兴趣使用GCC X86内置函数.

c x86 gcc sse simd

46
推荐指数
3
解决办法
2万
查看次数

在x86上做水平浮点矢量和的最快方法

你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?

SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?

"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)

floating-point optimization x86 assembly sse

41
推荐指数
4
解决办法
2万
查看次数

如何在没有编译器浪费指令归零上层元素的情况下将标量合并到向量中?英特尔内在函数的设计限制?

我没有特定的用例; 我问这是否真的是英特尔内在函数中的设计缺陷/限制,或者我是否只是遗漏了某些内容.

如果你想将标量浮点数与现有向量相结合,那么在没有高元素归零或使用英特尔内在函数将标量广播到向量中的情况下似乎没有办法实现.我没有研究过GNU C本机向量扩展和相关的内置函数.

如果额外的内在优化了,这不会太糟糕,但它不与gcc(5.4或6.2).也没有好的方法可以使用pmovzxinsertps作为负载,因为他们的内在函数只采用向量args的相关原因.(并且gcc不会将标量 - >向量加载到asm指令中.)

__m128 replace_lower_two_elements(__m128 v, float x) {
  __m128 xv = _mm_set_ss(x);        // WANTED: something else for this step, some compilers actually compile this to a separate insn
  return _mm_shuffle_ps(v, xv, 0);  // lower 2 elements are both x, and the garbage is gone
}
Run Code Online (Sandbox Code Playgroud)

gcc 5.3 -march = nehalem -O3输出,启用SSE4.1并调整该Intel CPU :(没有SSE4.1会更糟;多个指令将上层元素归零).

    insertps  xmm1, xmm1, 0xe    # pointless zeroing of upper elements.  shufps only reads the low element of xmm1 …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc sse intrinsics

8
推荐指数
1
解决办法
601
查看次数

在x86-64 SysV ABI中,高位参数和返回值寄存器是否允许垃圾?

除了其他方面,x86-64 SysV ABI指定了如何在寄存器中传递函数参数(第一个参数in rdi,then rsi等等),以及如何传回整数返回值(in rax和then rdx表示非常大的值).

然而,我找不到的是当传递小于64位的类型时,参数或返回值寄存器的高位应该是什么.

例如,对于以下功能:

void foo(unsigned x, unsigned y);
Run Code Online (Sandbox Code Playgroud)

... x将被传入rdiyrsi,但他们只是32位.不要的高32位rdirsi必须为零?直观地说,我会假设是,但是所有gcc,clang和icc 生成代码mov在开始时都有特定的指令将高位清零,所以看起来编译器假定不然.

类似地,编译器似乎假设rax如果返回值小于64 位,则返回值的高位可能具有垃圾位.例如,以下代码中的循环:

unsigned gives32();
unsigned short gives16();

long sum32_64() {
  long total = 0;
  for (int i=1000; i--; ) {
    total += gives32();
  }
  return total;
}

long sum16_64() {
  long total = 0;
  for (int i=1000; i--; ) {
    total += …
Run Code Online (Sandbox Code Playgroud)

linux x86 x86-64 calling-convention

8
推荐指数
1
解决办法
403
查看次数

如何使用_mm_extract_ps SSE GCC instrinc函数在C/C++中将hex float转换为float

我正在为二维卷积编写SSE代码,但SSE文档非常稀疏.我正在使用_mm_dp_ps计算点积并使用_mm_extract_ps来获得点积结果,但_mm_extract_ps返回表示浮点数的十六进制,我无法弄清楚如何将此十六进制浮点数转换为常规浮点数.我可以使用返回浮点数的__builtin_ia32_vec_ext_v4sf,但我想保持与其他编译器的兼容性.

_mm_extract_ps (__m128 __X, const int __N)
{
  union { int i; float f; } __tmp;
  __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N);
  return __tmp.i;
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

感谢一点帮助.

OpenSUSE 11.2
GCC 4.4.1
C++
编译器选项
-fopenmp -Wall -O3 -msse4.1 -march = core2
链接器选项
-lgomp -Wall -O3 -msse4.1 -march = core2

c++ floating-point hex gcc sse

6
推荐指数
1
解决办法
1965
查看次数

如何将XMM 128位寄存器拆分为两个64位整数寄存器?

如何将128位xmm寄存器拆分为两个64位quadwords?

我输入的字数非常多xmm1,想要将较高的四字r9和较低的四字输入r10,或RAXRDX

movlpdmovhpd仅与reg到mem兼容,反之亦然。

x86 assembly sse

6
推荐指数
1
解决办法
1180
查看次数

使用(float&)int工作类型punning,(float const&)int转换为(float)int而不是?

VS2019,发布,x86.

template <int i> float get() const {
    int f = _mm_extract_ps(fmm, i);
    return (float const&)f;
}
Run Code Online (Sandbox Code Playgroud)

使用return (float&)f;编译器时使用

extractps m32, ...
movss xmm0, m32
Run Code Online (Sandbox Code Playgroud)

.正确的结果

使用return (float const&)f;编译器时使用

extractps eax, ...
movd xmm0, eax
Run Code Online (Sandbox Code Playgroud)

.错误的结果

T&和T const&首先是T然后是const的主要思想.Const只是程序员的某种协议.你知道你可以解决它.但汇编代码中没有任何const,但是类型为float IS.我认为对于float和float const而言它必须是汇编中的浮点表示(cpu寄存器).我们可以使用中间int reg32,但最终解释必须是float.

而此时它看起来像回归,因为这之前工作正常.并且在这种情况下使用float也绝对是奇怪的,因为我们不应该考虑浮动const和安全性而是浮动的临时变量并且确实值得怀疑.

微软回答:

嗨Truthfinder,感谢自成一体的复制品.碰巧,这种行为实际上是正确的.正如我的同事@Xiang Fan [MSFT]在内部电子邮件中所述:

由[a c-style cast]执行的转换尝试以下序列:(4.1) - const_cast(7.6.1.11),(4.2) - static_cast(7.6.1.9),(4.3) - static_cast后跟const_cast ,(4.4) - reinterpret_cast(7.6.1.10)或(4.5) - reinterpret_cast后跟const_cast,

如果转换可以用上面列出的多种方式解释,则使用列表中首先出现的解释.

所以在你的情况下,(const float&)被转换为static_cast,其效果是"初始化表达式被隐式转换为类型为"cv1 T1"的prvalue.应用临时实现转换并将引用绑定到结果".

但在另一种情况下,(float&)被转换为reinterpret_cast,因为static_cast无效,这与reinterpret_cast(&operand)相同.

您正在观察的实际"错误"是一个强制转换:"将浮点型值"1.0"转换为等效的int-typed值"1"",而另一个强制转换说"将1.0的位表示形式转换为一个浮点数,然后将这些位解释为int".

出于这个原因,我们建议不要使用c风格的演员表.

谢谢!

MS论坛链接:https://developercommunity.visualstudio.com/content/problem/411552/extract-ps-intrinsics-bug.html

有任何想法吗?

PS我真正想要的是什么:

float val …
Run Code Online (Sandbox Code Playgroud)

c++ assembly sse intrinsics visual-c++

6
推荐指数
2
解决办法
299
查看次数

如何计算 __m128 变量。(另外 _mm_blendv_ps 是做什么的)?

所以我阅读了英特尔关于 _mm_blendv_ps 的文档,但不太明白该函数的真正作用。所以我写了下面的代码:

    __m128 a = { 18.0,4.0,19.0,21.0 };
    __m128 b = { 67.0,92.0,888.0,47.0 };
    __m128 mask = { 1.0,0.0,0.0,1.0 };

    __m128 result = _mm_blendv_ps(a, b, mask);
    cout << "Result is: " << result[0] << " " << result[1] << " " << result[2] << " " << result[4] << endl;
Run Code Online (Sandbox Code Playgroud)

但我收到错误“没有运算符 [] 与这些操作数匹配”。为什么我无法访问结果?结果不是32位浮点向量吗?

那么为什么我无法访问结果呢?我怎样才能访问它?cout 的结果是什么(blendv 做什么)?

c++ sse simd

0
推荐指数
1
解决办法
359
查看次数