Created
January 29, 2013 10:53
-
-
Save larsw/4663449 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Diagnostics; | |
| using Mono.Simd; | |
| using System.Runtime.CompilerServices; | |
| namespace VectorizedQueryTest | |
| { | |
| class Program | |
| { | |
| static bool MinimalSimdSupport() | |
| { | |
| return SimdRuntime.IsMethodAccelerated (typeof (Vector4f), "op_Addition") && | |
| SimdRuntime.IsMethodAccelerated (typeof (Vector4f), "op_Multiply") && | |
| SimdRuntime.IsMethodAccelerated (typeof (VectorOperations), "Shuffle", typeof (Vector4f), typeof (ShuffleSel)); | |
| } | |
| static bool EnhancedSimdSupport() | |
| { | |
| return SimdRuntime.IsMethodAccelerated (typeof (VectorOperations), "HorizontalAdd", typeof (Vector4f), typeof (Vector4f)) && | |
| SimdRuntime.IsMethodAccelerated (typeof (Vector4f), "op_Multiply"); | |
| } | |
| static void Main(string[] args) | |
| { | |
| // Console.WriteLine("Minimal SIMD Support: " + MinimalSimdSupport()); | |
| // Console.WriteLine("Enhanched SIMD Support: " + EnhancedSimdSupport()); | |
| // SELECT * FROM Table WHERE ColumnA < ColumnB | |
| int rowCount = 10000000; // 10M | |
| var rand = new Random(); | |
| var rowids = new int[rowCount]; | |
| var columna = new int[rowids.Length]; | |
| var columnb = new int[rowids.Length]; | |
| var result = new int[rowids.Length + 1]; | |
| var pos = 0; | |
| for (int i = 0; i < rowids.Length; i++) | |
| { | |
| rowids[i] = i; | |
| columna[i] = rand.Next(); | |
| columnb[i] = rand.Next(); | |
| } | |
| var columnbVector = new Vector4i(); | |
| var columnaVector = new Vector4i(); | |
| var rowIdBlock = new int[4]; | |
| // Start of performance measuring. | |
| var watch = new Stopwatch(); | |
| watch.Start(); | |
| for (int i = 0; i < rowids.Length; i += 4) | |
| { | |
| // columnaVector.X = columna[i]; | |
| // columnaVector.Y = columna[i + 1]; | |
| // columnaVector.Z = columna[i + 2]; | |
| // columnaVector.W = columna[i + 3]; | |
| columnaVector = columna.GetVector(i); | |
| // columnbVector.X = columnb[i]; | |
| // columnbVector.Y = columnb[i + 1]; | |
| // columnbVector.Z = columnb[i + 2]; | |
| // columnbVector.W = columnb[i + 3]; | |
| columnbVector = columnb.GetVector(i); | |
| var mask = columnbVector.CompareGreaterThan(columnaVector); | |
| // To compare greater than or equals, compare equals, compare greater than, and then and the two masks together. Use bitwise OR. | |
| // rowIdBlock[0] = rowids[i]; | |
| // rowIdBlock[1] = rowids[i + 1]; | |
| // rowIdBlock[2] = rowids[i + 2]; | |
| // rowIdBlock[3] = rowids[i + 3]; | |
| // SIMD_Process(mask, rowids, i, result, ref pos); | |
| if ((mask.X | mask.Y | mask.Z | mask.W) < 0) // Profiler says 4.8% spent here. | |
| { | |
| // for (int j = 0; j < 4; j++) | |
| // { | |
| var tmp = mask[0] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[i]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[1] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[i + 1]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[2] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[i + 2]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[3] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[i + 3]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| // } | |
| } | |
| } | |
| result[pos] = 0; | |
| watch.Stop(); // 114 milliseconds to process 10M rows. | |
| // Debug.WriteLine(watch.Elapsed); | |
| Console.WriteLine(watch.Elapsed); | |
| // Console.ReadKey(); | |
| } | |
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static void SIMD_Process(Vector4i mask, int[] rowids, int rowidsStart, int[] result, ref int pos) | |
| { | |
| if ((mask.X | mask.Y | mask.Z | mask.W) < 0) // Profiler says 4.8% spent here. | |
| { | |
| // for (int j = 0; j < 4; j++) | |
| // { | |
| var tmp = mask[0] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[rowidsStart]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[1] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[rowidsStart + 1]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[2] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[rowidsStart + 2]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| tmp = mask[3] & 1; // Profiler says 10.3% spent here. | |
| result[pos] = rowids[rowidsStart + 3]; // Profiler says 8.7% spent here. | |
| pos += tmp; // Profiler says 5.6% spent here. | |
| // } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment