Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- using System.Threading;
- using System.Threading.Tasks;
- namespace Alignment
- {
- public class MemoryAlignmentAttribute : Attribute
- {
- public int Alignment { get; }
- public MemoryAlignmentAttribute(int alignment)
- {
- Alignment = alignment;
- }
- }
- [StructLayout(LayoutKind.Sequential)]
- public class Foo
- {
- public Bar Bar;
- }
- [MemoryAlignment(8)] // <== Would be nice
- [StructLayout(LayoutKind.Explicit)]
- public struct Bar
- {
- [FieldOffset(0)]
- public int Int1;
- [FieldOffset(4)]
- public int Int2;
- [FieldOffset(0)]
- public long Long;
- }
- class Program
- {
- static unsafe void Main(string[] args)
- {
- // Results on my machine:
- // Aligned: 00:00:00.1393711
- // Unaligned: 00:00:06.8153094
- if (Environment.Is64BitProcess)
- {
- // Replacing "x86" by "x86!" below will make the execution as fast for aligned/unaligned
- // If anyone want to explain why I would be very grateful! I'm missing something here
- //System.Console.WriteLine(x86!);
- Console.WriteLine("x86");
- return;
- }
- const int Iteration = 1000000;
- const int Concurrency = 2;
- Foo foo = GetAligned();
- List<Task> tasks = new List<Task>();
- Stopwatch sw = Stopwatch.StartNew();
- for (int c = 0; c < Concurrency; c++)
- {
- tasks.Add(Task.Factory.StartNew(() =>
- {
- for (int i = 0; i < Iteration; i++)
- {
- while (true)
- {
- long original = Volatile.Read(ref foo.Bar.Long);
- Bar bar = new Bar();
- bar.Long = original;
- ++bar.Int1;
- ++bar.Int2;
- if (Interlocked.CompareExchange(ref foo.Bar.Long, bar.Long, original) == original)
- break;
- }
- }
- }, TaskCreationOptions.LongRunning));
- }
- Task.WaitAll(tasks.ToArray());
- Console.WriteLine("Aligned: " + sw.Elapsed);
- foo = GetUnaligned();
- tasks = new List<Task>();
- sw = Stopwatch.StartNew();
- for (int c = 0; c < Concurrency; c++)
- {
- tasks.Add(Task.Factory.StartNew(() =>
- {
- for (int i = 0; i < Iteration; i++)
- {
- while (true)
- {
- long original = Volatile.Read(ref foo.Bar.Long);
- Bar bar = new Bar();
- bar.Long = original;
- ++bar.Int1;
- ++bar.Int2;
- if (Interlocked.CompareExchange(ref foo.Bar.Long, bar.Long, original) == original)
- break;
- }
- }
- }, TaskCreationOptions.LongRunning));
- }
- Task.WaitAll(tasks.ToArray());
- Console.WriteLine("Unaligned: " + sw.Elapsed);
- }
- static unsafe Foo GetAligned()
- {
- while (true)
- {
- var foo = new Foo();
- fixed (long* ptr = &foo.Bar.Long)
- {
- if (((int)ptr & 7) == 0)
- return foo;
- }
- }
- }
- static unsafe Foo GetUnaligned()
- {
- while (true)
- {
- var foo = new Foo();
- fixed (long* ptr = &foo.Bar.Long)
- {
- if (((int)ptr & 7) != 0)
- return foo;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement