c++simdc++23c++-experimental

Storing and retrieving number from C++23 experimental simd gives random result


I wrote this small peice of code to test the problem. This is the code I have:

#include <experimental/simd>

namespace stdx = std::experimental;

using vfloat4 = stdx::fixed_size_simd<float, 4>;
using vint4 = stdx::fixed_size_simd<int, 4>;

inline void print_vint4(vint4 vi4)
{
    printf("%i %i %i %i\n", vi4[0], vi4[1], vi4[2], vi4[3]);
}

int main()
{
    vint4 _v = 4;
    printf(">> %i\n", _v[0]);
    printf(">> %i\n", _v[0]);
    print_vint4(_v);
    return 1;
}

And this is what it prints:

>> 1233123648
>> 1233123664
1233123568 1233123552 1233123536 1233123520

Even the two identical printf functions print different numbers. The numbers are different every time the app is run (sometimes positive, sometimes negative).

Also, when I use vfloat4 instead of vint4 (and the appropriate format for printf), all the printed numbers are zero. I don't really know where to begin debugging this and I can't see what's causing it.


(I know this code is experimental and low-level, so I thought I'd include some specs in case they're needed)

Compiler: GCC 14.2.0 (running in MSYS2)

OS: Windows 10, 64bit

CPU: Intel i5, 12th gen, x86_64


Solution

  • std::experimental::simd::operator[] returns a reference type when called on an lvalue which is an implementation defined proxy object to the individual elements of the smid object

    This is a type that is not compatible with printf and so when you tell it to treat it as an int then you get whatever printf tries to do to convert the reference object into an int. If you manually cast each elements to an int like

    inline void print_vint4(vint4 vi4)
    {
        printf("%i %i %i %i\n", (int)vi4[0], (int)vi4[1], (int)vi4[2], (int)vi4[3]);
    }
    
    int main()
    {
        vint4 _v = 4;
        printf(">> %i\n", (int)_v[0]);
        printf(">> %i\n", (int)_v[0]);
        print_vint4(_v);
        return 1;
    }
    

    then the code will output

    >> 4
    >> 4
    4 4 4 4
    

    as seen in this live example.


    Another option is to not use printf and instead use cout like

    inline void print_vint4(vint4 vi4)
    {
        std::cout << vi4[0] << " " << vi4[1] << " " << vi4[2] << " " << vi4[3] << "\n";
    }
    
    int main()
    {
        vint4 _v = 4;
        std::cout << ">> " << _v[0] << "\n";
        std::cout << ">> " << _v[0] << "\n";
        print_vint4(_v);
        return 1;
    }
    

    which also has the same output as seen in this live example.