-
-
Save thoward/4651807 to your computer and use it in GitHub Desktop.
This file contains 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; | |
namespace VectorizedQueryTest | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// 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(); | |
} | |
// Start of performance measuring. | |
var watch = new Stopwatch(); | |
watch.Start(); | |
var columnbVector = new Vector4i(); | |
var columnaVector = new Vector4i(); | |
var rowIdBlock = new int[4]; | |
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]; | |
columnbVector.X = columnb[i]; | |
columnbVector.Y = columnb[i + 1]; | |
columnbVector.Z = columnb[i + 2]; | |
columnbVector.W = columnb[i + 3]; | |
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, rowIdBlock, result, ref pos); | |
} | |
result[pos] = 0; | |
watch.Stop(); // 197 milliseconds to process 10M rows. | |
Debug.WriteLine(watch.Elapsed); | |
Console.WriteLine(watch.Elapsed); | |
Console.ReadKey(); | |
} | |
public static void SIMD_Process(Vector4i mask, int[] rowids, int[] result, ref int pos) | |
{ | |
if ((mask.X | mask.Y | mask.Z | mask.W) == 0) return; | |
const int S = 4; | |
for (int j = 0; j < S; j++) | |
{ | |
var tmp = mask[j] & 1; | |
result[pos] = rowids[j]; | |
pos += tmp; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment