public static uint[][] HistogramByteComponentsPar(ulong[] inArray, Int32 l, Int32 r) { const int numberOfBins = 256; const int numberOfDigits = sizeof(ulong); uint[][] countLeft = new uint[numberOfDigits][]; for (int i = 0; i < numberOfDigits; i++) { countLeft[i] = new uint[numberOfBins]; } if (l > r) // zero elements to compare { return(countLeft); } if ((r - l + 1) <= ThresholdByteCount) { var union = new Algorithm.UInt64ByteUnion(); for (int current = l; current <= r; current++) // Scan the array and count the number of times each digit value appears - i.e. size of each bin { union.integer = inArray[current]; countLeft[0][union.byte0]++; countLeft[1][union.byte1]++; countLeft[2][union.byte2]++; countLeft[3][union.byte3]++; countLeft[4][union.byte4]++; countLeft[5][union.byte5]++; countLeft[6][union.byte6]++; countLeft[7][union.byte7]++; } return(countLeft); } int m = (r + l) / 2; uint[][] countRight = new uint[numberOfDigits][]; for (int i = 0; i < numberOfDigits; i++) { countRight[i] = new uint[numberOfBins]; } Parallel.Invoke( () => { countLeft = HistogramByteComponentsPar(inArray, l, m); }, () => { countRight = HistogramByteComponentsPar(inArray, m + 1, r); } ); // Combine left and right results for (int i = 0; i < numberOfDigits; i++) { for (int j = 0; j < numberOfBins; j++) { countLeft[i][j] += countRight[i][j]; } } return(countLeft); }
static uint[][] HistogramByteComponentsParInner(ulong[] inArray, Int32 l, Int32 r, int parallelThreshold = 16 * 1024) { const int numberOfBins = 256; const int numberOfDigits = sizeof(ulong); uint[][] countLeft = null; uint[][] countRight = null; if (l > r) // zero elements to compare { countLeft = new uint[numberOfDigits][]; for (int i = 0; i < numberOfDigits; i++) { countLeft[i] = new uint[numberOfBins]; } return(countLeft); } if ((r - l + 1) <= parallelThreshold) { countLeft = new uint[numberOfDigits][]; for (int i = 0; i < numberOfDigits; i++) { countLeft[i] = new uint[numberOfBins]; } uint[] countLeft0 = countLeft[0]; uint[] countLeft1 = countLeft[1]; uint[] countLeft2 = countLeft[2]; uint[] countLeft3 = countLeft[3]; uint[] countLeft4 = countLeft[4]; uint[] countLeft5 = countLeft[5]; uint[] countLeft6 = countLeft[6]; uint[] countLeft7 = countLeft[7]; var union = new Algorithm.UInt64ByteUnion(); for (int current = l; current <= r; current++) // Scan the array and count the number of times each digit value appears - i.e. size of each bin { union.integer = inArray[current]; countLeft0[union.byte0]++; countLeft1[union.byte1]++; countLeft2[union.byte2]++; countLeft3[union.byte3]++; countLeft4[union.byte4]++; countLeft5[union.byte5]++; countLeft6[union.byte6]++; countLeft7[union.byte7]++; } return(countLeft); } int m = (r + l) / 2; Parallel.Invoke( () => { countLeft = HistogramByteComponentsParInner(inArray, l, m, parallelThreshold); }, () => { countRight = HistogramByteComponentsParInner(inArray, m + 1, r, parallelThreshold); } ); // Combine left and right results for (int i = 0; i < numberOfDigits; i++) { for (int j = 0; j < numberOfBins; j++) { countLeft[i][j] += countRight[i][j]; } } return(countLeft); }