标签: sse

xmm 指令 - 内存源操作数的分段错误

我正在尝试使用 XMM 寄存器使用 SSE2 指令在汇编语言中将 4 个数字添加到其他 4 个数字中。我确实成功了,但我遇到了一些我不明白的事情。如果我以这种方式添加:

movdqu xmm0, oword [var1]
movdqu xmm1, oword [var2]
paddd xmm0, xmm1
movdqu oword [var1], xmm0 
Run Code Online (Sandbox Code Playgroud)

它工作得很好。

但如果我这样尝试:

movdqu xmm0, oword [var1]
paddd xmm0, oword [var2]
movdqu oword [var1], xmm0 
Run Code Online (Sandbox Code Playgroud)

它给了我一个分段错误。

第二种方法有什么问题?我正在使用 Nasm、Intel Atom N270、Linux Mint 12 32 位

x86 assembly sse simd memory-alignment

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

如何添加 8 字节长整数的每个字节?

我正在学习如何在视频应用程序中使用英特尔 MMX 和 SSE 指令。我有一个 8 字节的字,我想将所有 8 个字节相加并产生一个整数作为结果。直接的方法是连续 7 次移动和添加,但这很慢。这样做的最快方法是什么?是否有针对此的 MMX 或 SSE 指令?

这是这样做的缓慢方法

unsigned long PackedWord = whatever....
int byte1 = 0xff & (PackedWord);
int byte2 = 0xff & (PackedWord >> 8);
int byte3 = 0xff & (PackedWord >> 16);
int byte4 = 0xff & (PackedWord >> 24);
int byte5 = 0xff & (PackedWord >> 32);
int byte6 = 0xff & (PackedWord >> 40);
int byte7 = 0xff & (PackedWord >> 48);
int byte8 = 0xff & …
Run Code Online (Sandbox Code Playgroud)

c assembly sse mmx

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

性能 AVX/SSE 程序集与内在函数

我只是想检查优化一些基本例程的最佳方法。在这种情况下,我尝试了将 2 个浮点向量相乘的非常简单的示例:

void Mul(float *src1, float *src2, float *dst)
{
    for (int i=0; i<cnt; i++) dst[i] = src1[i] * src2[i];
};
Run Code Online (Sandbox Code Playgroud)

普通的 C 实现非常慢。我使用 AVX 做了一些外部 ASM,也尝试使用内在函数。这些是测试结果(时间越小越好):

ASM: 0.110
IPP: 0.125
Intrinsics: 0.18
Plain C++: 4.0
Run Code Online (Sandbox Code Playgroud)

(使用 MSVC 2013、SSE2 编译,尝试过 Intel 编译器,结果几乎相同)

正如您所看到的,我的 ASM 代码甚至击败了 Intel Performance Primitives(可能是因为我做了很多分支以确保我可以使用 AVX 对齐指令)。但我个人更喜欢使用内在方法,它更易于管理,我认为编译器应该在优化所有分支和内容方面做得最好(我的 ASM 代码在这方面很糟糕,但速度更快)。所以这是使用内在函数的代码:

    int i;
    for (i=0; (MINTEGER)(dst + i) % 32 != 0 && i < cnt; i++) dst[i] = src1[i] * src2[i];

    if ((MINTEGER)(src1 + i) % 32 …
Run Code Online (Sandbox Code Playgroud)

c++ assembly sse intrinsics avx

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

SSE 字节和半字交换

我想使用 SSE 内在函数翻译此代码。

for (uint32_t i = 0; i < length; i += 4, src += 4, dest += 4)
{
    uint32_t value = *(uint32_t*)src;
    *(uint32_t*)dest = ((value >> 16) & 0xFFFF) | (value << 16);
}
Run Code Online (Sandbox Code Playgroud)

有没有人知道执行 16 位字交换的内在因素?

c x86 sse simd intrinsics

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

gcc 4.8 AVX 优化错误:额外的代码插入?

很高兴 gcc 编译器 4.8 带有带有 -Ofast 选项的 AVX 优化。但是,我发现了一个有趣但愚蠢的错误,它增加了不必要的额外计算。也许我错了,所以有人可以给我一个解释吗?

原来的C++源代码如下:

#define N 1000007

float a[N],b[N],c[N],d[N],e[N];

int main(int argc, char *argv[]){
    cout << a << ' ' << b << ' ' << c << endl;
    for(int x=0; x<N; ++x){
        c[x] = 1/sqrt((a[x]+b[x]-c[x])*d[x]/e[x]);
    }
    return  0;
}
Run Code Online (Sandbox Code Playgroud)

代码在 Ubuntu 14.04.3 x86_64 中使用 g++ 4.8.4 编译: g++ -mavx avx.cpp -masm=intel -c -g -Wa,-ahl=avx.asm -Ofast

汇编源代码如下:

  90                    .LVL10:
  91 006b C5FC2825              vmovaps ymm4, YMMWORD PTR .LC0[rip]
  91      00000000 
  92 0073 31C0                  xor     eax, …
Run Code Online (Sandbox Code Playgroud)

optimization gcc sse g++ avx

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

SSE 指令 MOVSD(扩展:x86、x86-64 上的浮点标量和向量运算)

我对 MOVSD 汇编指令有些困惑。我写了一些计算矩阵乘法的数字代码,只是使用没有 SSE 内在函数的普通 C 代码。我什至不包括用于编译的 SSE2 内在函数的头文件。但是当我检查汇编器输出时,我看到:

1)使用128位向量寄存器XMM;2) 调用SSE2 指令MOVSD。

我知道 MOVSD 本质上是在单双精度浮点上运行的。它只使用 XMM 寄存器的低 64 位并将高 64 位设置为 0。但我只是不明白两件事:

1) 我从来没有给编译器任何使用 SSE2 的提示。另外,我使用的是 GCC 而不是英特尔编译器。据我所知,intel 编译器会自动寻找向量化的机会,但 GCC 不会。那么 GCC 怎么知道使用 MOVSD 的呢??或者,这个 x86 指令早在 SSE 指令集之前就已经存在了,而 SSE2 中的 _mm_load_sd() 内在函数只是为使用 XMM 寄存器进行标量计算提供向后兼容性?

2)为什么编译器不使用其他浮点寄存器,要么是80位浮点栈,要么是64位浮点寄存器??为什么必须使用 XMM 寄存器(通过设置高位 64 位 0 并实质上浪费该存储)?XMM 是否提供更快的访问?


顺便说一下,我还有一个关于 SSE2 的问题。我只是看不出 _mm_store_sd() 和 _mm_storel_sd() 之间的区别。两者都将较低的 64 位值存储到一个地址。有什么不同?性能差异??对齐方式不同??

谢谢你。


更新 1:

OKAY,很明显,当我第一次问这个问题时,我缺乏关于 CPU 如何管理浮点运算的一些基本知识。所以专家们往往认为我的问题是无稽之谈。由于我什至没有包含最短的示例 C 代码,因此人们可能也会认为这个问题含糊不清。在这里,我将提供一个评论作为答案,希望对任何不清楚现代 CPU 上的浮点运算的人有用。

c assembly sse x86-64 sse2

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

为什么和在何处 align 16 用于指令的 SSE 对齐?

我正在阅读 Apress 的现代 x86 汇编语言书籍。对于编程 64 位 SSE 示例,作者将align 16放在代码中的特定点上。例如

    .code
ImageUint8ToFloat_ proc frame
_CreateFrame U2F_,0,64               ; helper macros to create prolog
_SaveXmmRegs xmm10,xmm11,xmm12,xmm13 ; helper macros to create prolog

_EndProlog  ; helper macros to create prolog

...

shrd r8d,
pxor xmm5,xmm5

align 16  ; Why this is here ?
@@:
movdqa xmm0,xmmword ptr [rdx]
movdqa xmm10,xmmword ptr [rdx+16]

movdqa xmm2,xmm0
punpcklbw xmm0,xmm5
punpckhbw xmm2,xmm5
movdqa xmm1,xmm0
movdqa xmm3,xmm2

...
Run Code Online (Sandbox Code Playgroud)

作者解释说有必要放置align 16,因为我们使用的是 SSE,以便指令本身对齐。没关系。我的问题是为什么作者选择将align 16放在该特定位置。作为程序员,我应该如何决定 …

64-bit assembly sse

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

使用 SSE 对 8 位灰度图像进行最快的缩小

我有一个功能可以将 8 位图像缩小两倍。我之前已经用 SSE 优化了 rgb32 案例。现在我想对 gray8 案例做同样的事情。

在核心,有一个函数取两行像素数据,其工作方式如下:

/** 
 * Calculates the average of two rows of gray8 pixels by averaging four pixels.
 */
void average2Rows(const uint8_t* row1, const uint8_t* row2, uint8_t* dst, int size)
{
    for (int i = 0; i < size - 1; i += 2)
        *(dst++) = ((row1[i]+row1[i+1]+row2[i]+row2[i+1])/4)&0xFF;
}
Run Code Online (Sandbox Code Playgroud)

现在,我想出了一个 SSE 变体,它大约快三倍,但它确实涉及很多改组,我认为可能会做得更好。有人看到这里可以优化什么吗?

/* row1: 16 8-bit values A-P
 * row2: 16 8-bit values a-p
 * returns 16 8-bit values (A+B+a+b)/4, (C+D+c+d)/4, ..., …
Run Code Online (Sandbox Code Playgroud)

c++ x86 sse image-processing simd

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

SSE 错误 - 使用 m128i_i32 定义 __m128i 变量的字段

__m128i以这种方式定义变量时:

__m128i a;
a.m128i_i32[0] = 65000;
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误:请求'a'中的成员'm128i_i32',它是非类类型'__m128i {aka __vector(2) long long int}' a.m128i_i32[0] = 65000;

我已经包含了以下头文件:

#include <x86intrin.h>
#include <emmintrin.h>
#include <smmintrin.h>
Run Code Online (Sandbox Code Playgroud)

c++ sse

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

如何使用avx2将24位rgb转换为32位?

我已经用 SSSE3 完成了这个,现在我想知道这是否可以用 AVX2 完成以获得更好的性能?

我用一个零字节填充 24 位 rgb,使用来自Fast 24-bit array -> 32-bit array conversion 的代码?.

    static const __m128i mask = _mm_setr_epi8(0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1);
    for (size_t row = 0; row < height; ++row)
    {
        for (size_t column = 0; column < width; column += 16)
        {
            const __m128i *src = reinterpret_cast<const __m128i *>(in + row * in_pitch + column + (column << 1));
            __m128i *dst …
Run Code Online (Sandbox Code Playgroud)

rgb x86 sse simd avx2

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

标签 统计

sse ×10

assembly ×5

simd ×4

x86 ×4

c ×3

c++ ×3

avx ×2

intrinsics ×2

64-bit ×1

avx2 ×1

g++ ×1

gcc ×1

image-processing ×1

memory-alignment ×1

mmx ×1

optimization ×1

rgb ×1

sse2 ×1

x86-64 ×1