Skip to content

Instantly share code, notes, and snippets.

@eerhardt
Created June 25, 2018 15:45
Show Gist options
  • Save eerhardt/99071a3b6b00ddfe5ae02d9f85d4f9d6 to your computer and use it in GitHub Desktop.
Save eerhardt/99071a3b6b00ddfe5ae02d9f85d4f9d6 to your computer and use it in GitHub Desktop.
Parallel.For benchmark
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace ParallelForBenchmark
{
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<LightGBMDataSet>();
}
}
public class LightGBMDataSet
{
private const int numCol = 100;
private double[][] sampleValuePerColumn;
private int[][] sampleIndicesPerColumn;
int[] nonZeroCntPerColumn;
[GlobalSetup]
public void Setup()
{
sampleValuePerColumn = new double[numCol][];
sampleIndicesPerColumn = new int[numCol][];
nonZeroCntPerColumn = new int[numCol];
int estimateNonZeroCnt = 10;
for (int i = 0; i < numCol; i++)
{
sampleValuePerColumn[i] = new double[estimateNonZeroCnt];
sampleIndicesPerColumn[i] = new int[estimateNonZeroCnt];
}
}
[Benchmark]
public void Original()
{
DatasetOrig dataset = new DatasetOrig(
sampleValuePerColumn,
sampleIndicesPerColumn,
numCol,
nonZeroCntPerColumn,
0,
100,
"",
null);
}
[Benchmark]
public void NoParallel()
{
DatasetNoParallel dataset = new DatasetNoParallel(
sampleValuePerColumn,
sampleIndicesPerColumn,
numCol,
nonZeroCntPerColumn,
0,
100,
"",
null);
}
}
/// <summary>
/// Wrapper of Dataset object of LightGBM.
/// </summary>
internal sealed class DatasetOrig
{
private IntPtr _handle;
private int _lastPushedRowID;
public IntPtr Handle => _handle;
public unsafe DatasetOrig(double[][] sampleValuePerColumn,
int[][] sampleIndicesPerColumn,
int numCol,
int[] sampleNonZeroCntPerColumn,
int numSampleRow,
int numTotalRow,
string param, float[] labels, float[] weights = null, int[] groups = null)
{
_handle = IntPtr.Zero;
// Use GCHandle to pin the memory, avoid the memory relocation.
GCHandle[] gcValues = new GCHandle[numCol];
GCHandle[] gcIndices = new GCHandle[numCol];
try
{
double*[] ptrArrayValues = new double*[numCol];
int*[] ptrArrayIndices = new int*[numCol];
Parallel.For(0, numCol, i =>
{
gcValues[i] = GCHandle.Alloc(sampleValuePerColumn[i], GCHandleType.Pinned);
ptrArrayValues[i] = (double*)gcValues[i].AddrOfPinnedObject().ToPointer();
gcIndices[i] = GCHandle.Alloc(sampleIndicesPerColumn[i], GCHandleType.Pinned);
ptrArrayIndices[i] = (int*)gcIndices[i].AddrOfPinnedObject().ToPointer();
});
fixed (double** ptrValues = ptrArrayValues)
fixed (int** ptrIndices = ptrArrayIndices)
{
//LightGbmInterfaceUtils.Check(WrappedLightGbmInterface.DatasetCreateFromSampledColumn(
// (IntPtr)ptrValues, (IntPtr)ptrIndices, numCol, sampleNonZeroCntPerColumn, numSampleRow, numTotalRow,
// param, ref _handle));
}
}
finally
{
Parallel.For(0, numCol, i =>
{
if (gcValues[i].IsAllocated)
gcValues[i].Free();
if (gcIndices[i].IsAllocated)
gcIndices[i].Free();
});
}
//SetLabel(labels);
//SetWeights(weights);
//SetGroup(groups);
//Contracts.Assert(GetNumCols() == numCol);
//Contracts.Assert(GetNumRows() == numTotalRow);
}
}
internal sealed class DatasetNoParallel
{
private IntPtr _handle;
private int _lastPushedRowID;
public IntPtr Handle => _handle;
public unsafe DatasetNoParallel(double[][] sampleValuePerColumn,
int[][] sampleIndicesPerColumn,
int numCol,
int[] sampleNonZeroCntPerColumn,
int numSampleRow,
int numTotalRow,
string param, float[] labels, float[] weights = null, int[] groups = null)
{
_handle = IntPtr.Zero;
// Use GCHandle to pin the memory, avoid the memory relocation.
GCHandle[] gcValues = new GCHandle[numCol];
GCHandle[] gcIndices = new GCHandle[numCol];
try
{
double*[] ptrArrayValues = new double*[numCol];
int*[] ptrArrayIndices = new int*[numCol];
for (int i = 0; i < numCol; i++)
{
gcValues[i] = GCHandle.Alloc(sampleValuePerColumn[i], GCHandleType.Pinned);
ptrArrayValues[i] = (double*)gcValues[i].AddrOfPinnedObject().ToPointer();
gcIndices[i] = GCHandle.Alloc(sampleIndicesPerColumn[i], GCHandleType.Pinned);
ptrArrayIndices[i] = (int*)gcIndices[i].AddrOfPinnedObject().ToPointer();
};
fixed (double** ptrValues = ptrArrayValues)
fixed (int** ptrIndices = ptrArrayIndices)
{
//LightGbmInterfaceUtils.Check(WrappedLightGbmInterface.DatasetCreateFromSampledColumn(
// (IntPtr)ptrValues, (IntPtr)ptrIndices, numCol, sampleNonZeroCntPerColumn, numSampleRow, numTotalRow,
// param, ref _handle));
}
}
finally
{
for (int i = 0; i < numCol; i++)
{
if (gcValues[i].IsAllocated)
gcValues[i].Free();
if (gcIndices[i].IsAllocated)
gcIndices[i].Free();
};
}
//SetLabel(labels);
//SetWeights(weights);
//SetGroup(groups);
//Contracts.Assert(GetNumCols() == numCol);
//Contracts.Assert(GetNumRows() == numTotalRow);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment