Created
June 25, 2018 15:45
-
-
Save eerhardt/99071a3b6b00ddfe5ae02d9f85d4f9d6 to your computer and use it in GitHub Desktop.
Parallel.For benchmark
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 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