Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Vector8Float more efficient #1

Open
juliusfriedman opened this issue Dec 14, 2020 · 0 comments
Open

Make Vector8Float more efficient #1

juliusfriedman opened this issue Dec 14, 2020 · 0 comments

Comments

@juliusfriedman
Copy link
Owner

juliusfriedman commented Dec 14, 2020

Will effect all tests as the byte order of components would change.

Could also have properties which fall at the original offsets and give different names to ABCD

    /// <summary>
    /// A single <see cref="System.Numerics.Vector{double}"/> or dual <see cref="System.Numerics.Vector4"/>.
    /// Contains 4 <see cref="Vector4Half"/>
    /// </summary>
    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit, Size = Vector8Float.Size)]
    public struct Vector8Float
    {
        const int Size = sizeof(float) * 8;
        /// <summary>
        /// 4 Doubles
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(00)]
        public System.Numerics.Vector<double> Vector;

        /// <summary>
        /// 4 Floats
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(00)]
        public System.Numerics.Vector4 High;

        [System.Runtime.InteropServices.FieldOffset(00)]
        public float D;

        [System.Runtime.InteropServices.FieldOffset(04)]
        public float A;

        [System.Runtime.InteropServices.FieldOffset(08)]
        public float B;

        [System.Runtime.InteropServices.FieldOffset(12)]
        public float C;

        /// <summary>
        /// 4 Floats
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(16)]
        public System.Numerics.Vector4 Low;

        [System.Runtime.InteropServices.FieldOffset(16)]
        public float W;

        [System.Runtime.InteropServices.FieldOffset(20)]
        public float X;

        [System.Runtime.InteropServices.FieldOffset(24)]
        public float Y;

        [System.Runtime.InteropServices.FieldOffset(28)]
        public float Z;

        /// <summary>
        /// 4 Halfs
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(00)]
        public Vector4Half P;

        /// <summary>
        /// 4 Halfs
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(08)]
        public Vector4Half Q;

        /// <summary>
        /// 4 Halfs
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(16)]
        public Vector4Half R;

        /// <summary>
        /// 4 Halfs
        /// </summary>
        [System.Runtime.InteropServices.FieldOffset(24)]
        public Vector4Half S;

        /// <summary>
        /// Gets or Sets the Raw Binary data assoicated with the instance (32 bytes)
        /// </summary>
        public System.Span<byte> RawBytes
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            get { return System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.As<System.Numerics.Vector<double>, byte>(ref Vector), Vector8Float.Size); }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            set { value.CopyTo(RawBytes); }
        }

        /// <summary>
        /// Access elements by offset
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public float this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0: return D;
                    case 1: return A;
                    case 2: return B;
                    case 3: return C;
                    case 4: return W;
                    case 5: return X;
                    case 6: return Y;
                    case 7: return Z;
                    default: throw new System.ArgumentOutOfRangeException(nameof(index));
                }
            }
        }

        public Vector8Float(float[] eight) : this()
        {
            //Todo profile if the runtime optomizes load asm for this or if RawBytes copy is better
            //High = new System.Numerics.Vector4(eight[0], eight[1], eight[2], eight[3]);
            //Low = new System.Numerics.Vector4(eight[4], eight[5], eight[6], eight[7]);
            //Warning these are shifted [0] = 3, 
            //This means we have to change the variables used in the arc / circle math because/
            //they depend on a predefined order abcdwxyz
            //this order is dabcwxyz
            var c = System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.As<float, byte>(ref eight[0]), eight.Length * sizeof(float));
            c.CopyTo(RawBytes);
        }

        /// <summary>
        /// </summary>
        /// <param name="four"></param>
        public Vector8Float(double[] four) : this()
        {
            High = Low = default;
            Vector = new System.Numerics.Vector<double>(four);
        }

        /// <summary>
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="w"></param>
        public Vector8Float(double x, double y, double z, double w) 
            : this(new double[] { x, y, z, w }) { }

        /// <summary>
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <param name="d"></param>
        public Vector8Float(float a, float b, float c, float d) 
            : this(new float[] { a, b, c, d }) { }

        /// <summary>
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <param name="d"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="w"></param>
        public Vector8Float(float a, float b, float c, float d, float x, float y, float z, float w) : 
            this(new float[] { a, b, c, d, x, y, z, w }) { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="high"></param>
        /// <param name="low"></param>
        public Vector8Float(System.Numerics.Vector4 high, System.Numerics.Vector4 low) : this()
        {
            Vector = default;
            High = high;
            Low = low;
        }

        public override string ToString()=> string.Join(" ", High.ToString(), Low.ToString());
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant