Skip to content

Instantly share code, notes, and snippets.

@larsw
Created January 29, 2013 10:53
Show Gist options
  • Save larsw/4663449 to your computer and use it in GitHub Desktop.
Save larsw/4663449 to your computer and use it in GitHub Desktop.
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