Advertisement
Guest User

Untitled

a guest
May 24th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.08 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace Alignment
  9. {
  10. public class MemoryAlignmentAttribute : Attribute
  11. {
  12. public int Alignment { get; }
  13.  
  14. public MemoryAlignmentAttribute(int alignment)
  15. {
  16. Alignment = alignment;
  17. }
  18. }
  19.  
  20. [StructLayout(LayoutKind.Sequential)]
  21. public class Foo
  22. {
  23. public Bar Bar;
  24. }
  25.  
  26. [MemoryAlignment(8)] // <== Would be nice
  27. [StructLayout(LayoutKind.Explicit)]
  28. public struct Bar
  29. {
  30. [FieldOffset(0)]
  31. public int Int1;
  32.  
  33. [FieldOffset(4)]
  34. public int Int2;
  35.  
  36. [FieldOffset(0)]
  37. public long Long;
  38. }
  39.  
  40. class Program
  41. {
  42. static unsafe void Main(string[] args)
  43. {
  44. // Results on my machine:
  45. // Aligned: 00:00:00.1393711
  46. // Unaligned: 00:00:06.8153094
  47.  
  48. if (Environment.Is64BitProcess)
  49. {
  50. // Replacing "x86" by "x86!" below will make the execution as fast for aligned/unaligned
  51. // If anyone want to explain why I would be very grateful! I'm missing something here
  52. //System.Console.WriteLine(x86!);
  53. Console.WriteLine("x86");
  54. return;
  55. }
  56.  
  57. const int Iteration = 1000000;
  58. const int Concurrency = 2;
  59.  
  60. Foo foo = GetAligned();
  61. List<Task> tasks = new List<Task>();
  62. Stopwatch sw = Stopwatch.StartNew();
  63.  
  64. for (int c = 0; c < Concurrency; c++)
  65. {
  66. tasks.Add(Task.Factory.StartNew(() =>
  67. {
  68. for (int i = 0; i < Iteration; i++)
  69. {
  70. while (true)
  71. {
  72. long original = Volatile.Read(ref foo.Bar.Long);
  73. Bar bar = new Bar();
  74. bar.Long = original;
  75.  
  76. ++bar.Int1;
  77. ++bar.Int2;
  78.  
  79. if (Interlocked.CompareExchange(ref foo.Bar.Long, bar.Long, original) == original)
  80. break;
  81. }
  82.  
  83. }
  84. }, TaskCreationOptions.LongRunning));
  85. }
  86. Task.WaitAll(tasks.ToArray());
  87. Console.WriteLine("Aligned: " + sw.Elapsed);
  88.  
  89. foo = GetUnaligned();
  90. tasks = new List<Task>();
  91. sw = Stopwatch.StartNew();
  92. for (int c = 0; c < Concurrency; c++)
  93. {
  94. tasks.Add(Task.Factory.StartNew(() =>
  95. {
  96. for (int i = 0; i < Iteration; i++)
  97. {
  98. while (true)
  99. {
  100. long original = Volatile.Read(ref foo.Bar.Long);
  101. Bar bar = new Bar();
  102. bar.Long = original;
  103.  
  104. ++bar.Int1;
  105. ++bar.Int2;
  106.  
  107. if (Interlocked.CompareExchange(ref foo.Bar.Long, bar.Long, original) == original)
  108. break;
  109. }
  110.  
  111. }
  112. }, TaskCreationOptions.LongRunning));
  113. }
  114. Task.WaitAll(tasks.ToArray());
  115. Console.WriteLine("Unaligned: " + sw.Elapsed);
  116. }
  117.  
  118. static unsafe Foo GetAligned()
  119. {
  120. while (true)
  121. {
  122. var foo = new Foo();
  123.  
  124. fixed (long* ptr = &foo.Bar.Long)
  125. {
  126. if (((int)ptr & 7) == 0)
  127. return foo;
  128. }
  129. }
  130. }
  131.  
  132. static unsafe Foo GetUnaligned()
  133. {
  134. while (true)
  135. {
  136. var foo = new Foo();
  137.  
  138. fixed (long* ptr = &foo.Bar.Long)
  139. {
  140. if (((int)ptr & 7) != 0)
  141. return foo;
  142. }
  143. }
  144. }
  145. }
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement