小编fig*_*n93的帖子

为什么这个SIMD乘法不比非SIMD乘法快?

让我们假设我们有一个函数,每个函数乘以两个1000000双精度数组.在C/C++中,函数如下所示:

void mul_c(double* a, double* b)
{
    for (int i = 0; i != 1000000; ++i)
    {
        a[i] = a[i] * b[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器生成以下程序集-O2:

mul_c(double*, double*):
        xor     eax, eax
.L2:
        movsd   xmm0, QWORD PTR [rdi+rax]
        mulsd   xmm0, QWORD PTR [rsi+rax]
        movsd   QWORD PTR [rdi+rax], xmm0
        add     rax, 8
        cmp     rax, 8000000
        jne     .L2
        rep ret
Run Code Online (Sandbox Code Playgroud)

从上面的程序集看来,编译器似乎使用了SIMD指令,但每次迭代只会增加一倍.所以我决定在内联汇编中编写相同的函数,在那里我充分利用xmm0寄存器并一次乘以两个双精度:

void mul_asm(double* a, double* b)
{
    asm volatile
    (
        ".intel_syntax noprefix             \n\t"
        "xor    rax, rax                    \n\t"
        "0:                                 \n\t"
        "movupd …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly simd

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

如何在GCC内联汇编中使用标签?

我正在尝试学习x86-64内联汇编,并决定实现这个非常简单的交换方法,只需按顺序排序a并按b升序排序:

#include <stdio.h>

void swap(int* a, int* b)
{
    asm(".intel_syntax noprefix");
    asm("mov    eax, DWORD PTR [rdi]");
    asm("mov    ebx, DWORD PTR [rsi]");
    asm("cmp    eax, ebx");
    asm("jle    .L1");
    asm("mov    DWORD PTR [rdi], ebx");
    asm("mov    DWORD PTR [rsi], eax");
    asm(".L1:");
    asm(".att_syntax noprefix");
}

int main()
{
    int input[3];

    scanf("%d%d%d", &input[0], &input[1], &input[2]);

    swap(&input[0], &input[1]);
    swap(&input[1], &input[2]);
    swap(&input[0], &input[1]);

    printf("%d %d %d\n", input[0], input[1], input[2]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用此命令运行它时,上面的代码按预期工作:

> gcc main.c
> ./a.out
> 3 2 1
> 1 …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc inline-assembly

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

标签 统计

assembly ×2

c ×1

c++ ×1

gcc ×1

inline-assembly ×1

performance ×1

simd ×1