#How to implement something like __mm256_maskload_ps with @Vector

1 messages · Page 1 of 1 (latest)

compact quest
#
const data:[4]f64 = .{ 1.0, 2.0, 3.0, 4.0 };
var vec: @Vector(4, f64) = undefined;
inline for (0..4) |i| {
    vec[i] = data[i];
}

The asm code generated by the above zig code can load 4 f64 data from mem to ymm0 using vmovsd

But sometimes want to load partial data like 3 f64 data from mem to ymm0, and use vmaskmovsd in generated asm code to do it efficiently.
But I don't know how to achieve the above mask load effect in Zig without using inline asm.

dim wedge
#

i think the problem with using something like vmaskmov is that it's still creating a bitpacked 4xf64

#

and having a vector of like @Vector(3, f64) means all of the elements are bitpacked

#

i imagine llvm would generate something something vinsert if you were to try doing the same code but just using @Vector(3, f64) and manually moving them

#

i cant really think of any better codegen tho, did you have a specific usage of maskload you were trying to replicate?

hot belfry
#

nvm, misunderstood the question

compact quest
#

I'm writing a gemm micro_kernel, and some of the tilling chunks don't fill the vector rigister(256bit), and I'd like to use vmaskload to efficiently load these smaller chunks into the vector register.

#

But in this case the generated asm code doesn't use vmaskload, it uses other instructions by using intermediate registers and so on, which reduces performance.

safe compass
#

is it an option to load the 3 values + an undefined to a @Vector(4, f64)?

compact quest
#
const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    const data = try allocator.alignedAlloc(f64, 32, 3);
    data[0] = 1.0;
    data[1] = 2.0;
    data[2] = 3.0;

    var vec: @Vector(4, f64) = undefined;

    for (0..3) |i| {
        vec[i] = data[i];
    }

    std.debug.print("{d}\n", .{vec});
}

And the asm

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    const data = try allocator.alignedAlloc(f64, 32, 3);
    data[0] = 1.0;
 10047b5:    c5 f8 28 05 93 ba ff     vmovaps -0x456d(%rip),%xmm0        # 1000250 <__init_array_end+0x250>
 10047bc:    ff 
 10047bd:    48 b8 00 00 00 00 00     movabs $0x4008000000000000,%rax
 10047c4:    00 08 40 
 10047c7:    c5 f8 29 01              vmovaps %xmm0,(%rcx)
    data[1] = 2.0;
    data[2] = 3.0;
 10047cb:    48 89 41 10              mov    %rax,0x10(%rcx)

    var vec: @Vector(4, f64) = undefined;

    for (0..3) |i| {
        vec[i] = data[i];
 10047cf:    c5 fc 28 01              vmovaps (%rcx),%ymm0