小编Eti*_*e M的帖子

关于 uint64 到 double 的转换:为什么右移 1 后代码更简单?

为什么AsDouble1比 更简单AsDouble0

// AsDouble0(unsigned long):                          # @AsDouble0(unsigned long)
//         movq    xmm1, rdi
//         punpckldq       xmm1, xmmword ptr [rip + .LCPI0_0] # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
//         subpd   xmm1, xmmword ptr [rip + .LCPI0_1]
//         movapd  xmm0, xmm1
//         unpckhpd        xmm0, xmm1                      # xmm0 = xmm0[1],xmm1[1]
//         addsd   xmm0, xmm1
//         addsd   xmm0, xmm0
//         ret
double AsDouble0(uint64_t x) { return x * 2.0; }

// AsDouble1(unsigned long):                          # @AsDouble1(unsigned long)
//         shr     rdi
//         cvtsi2sd        xmm0, rdi …
Run Code Online (Sandbox Code Playgroud)

c++ assembly sse x86-64 floating-point-conversion

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

在 Zen 2 CPU 上使用 AVX2 实现的 GEMM 内核比 AVX2/FMA 更快

我尝试过加快玩具 GEMM 的实施速度。我处理 32x32 双精度块,为此我需要优化的 MM 内核。我可以访问 AVX2 和 FMA。

我在下面定义了两个代码(在 ASM 中,我为格式的粗糙性表示歉意),一个使用 AVX2 功能,另一个使用 FMA。

在不进行微观基准测试的情况下,我想尝试(理论上)理解为什么 AVX2 实现比 FMA 版本快 1.11 倍。以及可能如何改进这两个版本。

下面的代码适用于 3000x3000 双打 MM,并且内核是使用经典的朴素 MM 和可互换的最深循环来实现的。我使用 Ryzen 3700x/Zen 2 作为开发 CPU。

我没有尝试过积极展开,担心 CPU 可能会耗尽物理寄存器。

AVX2 32x32 MM 内核:

Block 82:
    imul r12, r15, 0xbb8
    mov rax, r11
    mov r13d, 0x0
    vmovupd ymm0, ymmword ptr [rdi+r12*8]
    vmovupd ymm1, ymmword ptr [rdi+r12*8+0x20]
    vmovupd ymm2, ymmword ptr [rdi+r12*8+0x40]
    vmovupd ymm3, ymmword ptr [rdi+r12*8+0x60]
    vmovupd ymm4, ymmword ptr [rdi+r12*8+0x80]
    vmovupd ymm5, …
Run Code Online (Sandbox Code Playgroud)

assembly simd avx micro-optimization matrix-multiplication

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

Clang的__restrict不一致?

我正在研究高度“可向量化”的代码,并注意到关于 C++ __restrict 关键字/扩展 ~,即使在简单的情况下,与 GCC 相比,Clang 的行为也是不同且不切实际的。

对于编译器生成的代码,速度减慢约 15 倍(在我的具体情况下,不是下面的示例)。

这是代码(也可在https://godbolt.org/z/sdGd43x75获取):

struct Param {
    int *x;
};

int foo(int *a, int *b) {
    *a = 5;
    *b = 6;
    // No significant optimization here, as expected (for clang/gcc)
    return *a + *b;
}

int foo(Param a, Param b) {
    *a.x = 5;
    *b.x = 6;
    // No significant optimization here, as expected (for clang/gcc)
    return *a.x + *b.x;
}

/////////////////////

struct ParamR {
    // "Restricted pointers assert …
Run Code Online (Sandbox Code Playgroud)

c++ vectorization clang pointer-aliasing restrict-qualifier

5
推荐指数
1
解决办法
810
查看次数

预处理器算法是否应该与编译的目标架构相匹配?

假设我有这个预处理器检查:

#if(-6 & 5)
    #error "No 2's complement signed int"
#endif
Run Code Online (Sandbox Code Playgroud)

如果我从二进制补码机交叉编译到二进制补码机,会发生什么情况。编译器会使用目标机器的算术,还是编译机器的算术?

谢谢

c preprocessor language-lawyer

3
推荐指数
1
解决办法
151
查看次数