标签: sse

使用SSE将4个浮点数乘以4个浮点数的最有效方法是什么?

我目前有以下代码:

float a[4] = { 10, 20, 30, 40 };
float b[4] = { 0.1, 0.1, 0.1, 0.1 };
asm volatile("movups (%0), %%xmm0\n\t"
             "mulps (%1), %%xmm0\n\t"             
             "movups %%xmm0, (%1)"             
             :: "r" (a), "r" (b));
Run Code Online (Sandbox Code Playgroud)

我首先要问几个问题:

(1)如果我要在16字节边界上对齐数组,它甚至可以工作吗?由于数组是在堆栈上分配的,因此对齐它们几乎是不可能的吗?

看到这篇文章的选定答案:堆栈变量是否由GCC __attribute __((aligned(x)))对齐?

(2)代码是否可以重构以提高效率?如果我将两个浮点数组都放在寄存器而不只是一个?

谢谢

c assembly gcc sse sse2

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

对SSE指令进行基准测试

我正在对一些SSE代码(将4个浮点数乘以4个浮点数)与传统的C代码进行基准测试.我认为我的基准代码在某种程度上必须是错误的,因为它似乎说非SSE代码比SSE快2-3倍.

有人能告诉我下面的基准测试代码有什么问题吗?并且可能建议另一种方法准确地显示SSE和非SSE代码的速度.

#include <time.h>
#include <string.h>
#include <stdio.h>

#define ITERATIONS 100000

#define MULT_FLOAT4(X, Y) ({ \
asm volatile ( \
    "movaps (%0), %%xmm0\n\t" \
    "mulps (%1), %%xmm0\n\t" \
    "movaps %%xmm0, (%1)" \
    :: "r" (X), "r" (Y)); })

int main(void)
{
    int i, j;
    float a[4] __attribute__((aligned(16))) = { 10, 20, 30, 40 };
    time_t timer, sse_time, std_time;

    timer = time(NULL);
    for(j = 0; j < 5000; ++j)
        for(i = 0; i < ITERATIONS; ++i) {
            float b[4] …
Run Code Online (Sandbox Code Playgroud)

benchmarking assembly gcc sse

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

movlps的NASM 64位立即地址给出“ dword数据超出范围”

我需要带有64位立即数地址的movlps指令,根据Intel手册,这应该是完全可能的。因此,如下所示:

movlps xmm0, [0x7fffffffffa0]
Run Code Online (Sandbox Code Playgroud)

但是我得到的是NASM将操作数大小截断为32位并打印相应的警告:

sample.s:6: warning: dword data exceeds bounds
Run Code Online (Sandbox Code Playgroud)

我尝试了不同形式的qword前缀,但没有成功。

assembly sse x86-64 nasm

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

比较SSE内在函数中的符号位

如何使用SSE内在函数创建一个掩码,指示两个打包浮点(__m128)的符号是否相同,例如比较a和b,其中a为[1.0 -1.0 0.0 2.0],b为[1.0 1.0 1.0 1.0]我们得到的所需面具是[true false true true].

c++ sse intrinsics

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

SSE FPU并行

我想知道是否可以与x87并行使用SSE.所以考虑下面的伪代码,

1:sse_insn 2:x87_insn

管道是否会并行执行1和2,假设它们可以并行执行?

c c++ assembly sse x87

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

利用64位寄存器的最酷的多操作技巧?(没有SIMD/SSE/AVX)

我总是渴望了解最极端的性能优化.最近,我一直在考虑开发大型寄存器.当我在64位寄存器中获得一位信息时,我感到内疚...所以我想知道如何一次比较多个16位的技巧(例如有用的时候很有可能没有)或类似的.对于检查至少一个元素是否设置了标志的最简单的例子是将这些64位与0寄存器进行xor并将其比较为> 0.在指令级别上,这将会利用instr.管道,但无论如何你只需要2个指令而不是128个(每个mov和cmp).多数民众赞成我称之为惊人的加速!

我知道缓存未命中是我们的cpus花费95%的时间,但我们假设缓存使用已经是最佳的.

特别是对于树,一次比较没有SIMD的多个值并获得单个childIndex以便下一步读取将是有用的.最后,指令应该最小化,并且不要因管道等待惩罚而受到太多损失.

我可以列出的其他操作:

当使用填充(例如5x11位)彼此相邻时,您可以并行执行5次加法,移位,减法和按位运算.或7x 8位.Ofc,需要以这种方式存储数据并有效地使用结果,而不会对位掩码提取/导入进行惩罚.

optimization assembly sse bit-manipulation

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

Canny算法中的非最大抑制:使用SSE进行优化

我有"荣幸"来改善其他人的以下代码的运行时间.(这是来自canny - 算法的非最大限制).我的第一个想法是使用SSE内在代码,我在这方面很新,所以我的问题是.

有没有机会这样做?如果是这样,有人可以给我一些提示吗?

void vNonMaximumSupression(
          float* fpDst, 
          float const*const fpMagnitude, 
          unsigned char  const*const ucpGradient,                                                                           ///< [in] 0 -> 0°, 1 -> 45°, 2 -> 90°, 3 -> 135°
int iXCount, 
int iXOffset, 
int iYCount, 
int ignoreX, 
int ignoreY)
{
    memset(fpDst, 0, sizeof(fpDst[0]) * iXCount * iXOffset);

    for (int y = ignoreY; y < iYCount - ignoreY; ++y)
    {
        for (int x = ignoreX; x < iXCount - ignoreX; ++x)
        {
            int idx = iXOffset * y + x;
            unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ sse computer-vision edge-detection canny-operator

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

如何知道在opencv中是否激活了SSE2

我有一个版本的OpenCV 2.4.10库,它是在Windows上为Intel X64构建的.

我怎么知道CV_SSE2是否有效?我没有代码.我只有libs,DLL和标题.

谢谢

c++ 64-bit opencv sse

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

使用SIMD/SSE进行水平运行差异和条件更新?

我想矢量化以下操作:

V[i+1] = max(V[i] - c, V[i+1]) for i=1 to n-1 (V[0] = 0)
Run Code Online (Sandbox Code Playgroud)

相应的天真伪代码是:

for (i=0; i < n; i++) {
  if (V[i]-c > V[i+1]) V[i+1] = V[i]-c
}
Run Code Online (Sandbox Code Playgroud)

哪些SIMD说明有用?

c c++ sse simd vectorization

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

对齐和SSE异常行为

我尝试与SSE合作,但遇到了一些奇怪的行为。

我编写了简单的代码,用于将两个字符串与SSE Intrinsics进行比较,然后运行它并起作用。但是后来我明白了,在我的代码中,指针之一仍然没有对齐,但是我使用了_mm_load_si128指令,它要求指针在16字节边界上对齐。

//Compare two different, not overlapping piece of memory
__attribute((target("avx"))) int is_equal(const void* src_1, const void* src_2, size_t size)
{
    //Skip tail for right alignment of pointer [head_1]
    const char* head_1 = (const char*)src_1;
    const char* head_2 = (const char*)src_2;
    size_t tail_n = 0;
    while (((uintptr_t)head_1 % 16) != 0 && tail_n < size)
    {                                
        if (*head_1 != *head_2)
            return 0;
        head_1++, head_2++, tail_n++;
    }

    //Vectorized part: check equality of memory with SSE4.1 instructions
    //src1 - …
Run Code Online (Sandbox Code Playgroud)

c c++ sse intel simd

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