Memory alignment of classes in c#?

后端 未结 6 792
不思量自难忘°
不思量自难忘° 2020-12-17 15:35

(btw. This refers to 32 bit OS)

SOME UPDATES:

  • This is definitely an alignment issue

  • Sometimes the alignment (for whatever reason?) i

6条回答
  •  一整个雨季
    2020-12-17 15:59

    To prove the concept of misalignment of objects on heap in .NET you can run following code and you'll see that now it always runs fast. Please don't shoot me, it's just a PoC, but if you are really concerned about performance you might consider using it ;)

    public static class AlignedNew
    {
        public static T New() where T : new()
        {
            LinkedList candidates = new LinkedList();
            IntPtr pointer = IntPtr.Zero;
            bool continue_ = true;
    
            int size = Marshal.SizeOf(typeof(T)) % 8;
    
            while( continue_ )
            {
                if (size == 0)
                {
                    object gap = new object();
                }
    
                candidates.AddLast(new T());
    
                GCHandle handle = GCHandle.Alloc(candidates.Last.Value, GCHandleType.Pinned);
                pointer = handle.AddrOfPinnedObject();
                continue_ = (pointer.ToInt64() % 8) != 0 || (pointer.ToInt64() % 64) == 24;
    
                handle.Free();
    
                if (!continue_)
                    return candidates.Last.Value;
            }
    
            return default(T);
        }
    }
    
    class Program
    {
    
        [StructLayoutAttribute(LayoutKind.Sequential)]
        public class Variable
        {
            public double Value;
        }
    
        static void Main()
        {
    
            const int COUNT = 10000000;
    
            while (true)
            {
    
                var x = AlignedNew.New();
    
    
                for (int inner = 0; inner < 5; ++inner)
                {
    
                    var stopwatch = Stopwatch.StartNew();
    
                    var total = 0.0;
                    for (int i = 1; i <= COUNT; ++i)
                    {
                        x.Value = i;
                        total += x.Value;
                    }
                    if (Math.Abs(total - 50000005000000.0) > 1)
                        throw new ApplicationException(total.ToString());
    
    
                    Console.Write("{0}, ", stopwatch.ElapsedMilliseconds);
                }
                Console.WriteLine();
            }
    
        }
    }
    

提交回复
热议问题