Beispiel #1
0
        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);
        }