Пример #1
0
        public static uint[][] HistogramByteComponents(uint[] inArray, Int32 l, Int32 r)
        {
            const int numberOfBins   = 256;
            const int numberOfDigits = sizeof(uint);

            uint[][] count = new uint[numberOfDigits][];
            for (int i = 0; i < numberOfDigits; i++)
            {
                count[i] = new uint[numberOfBins];
            }
#if true
            var union = new UInt32ByteUnion();
            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];
                count[0][union.byte0]++;
                count[1][union.byte1]++;
                count[2][union.byte2]++;
                count[3][union.byte3]++;
            }
#else
            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
            {
                uint value = inArray[current];
                count[0][value & 0xff]++;
                count[1][(value & 0xff00) >> 8]++;
                count[2][(value & 0xff0000) >> 16]++;
                count[3][(value & 0xff000000) >> 24]++;
            }
#endif
            return(count);
        }
Пример #2
0
        public static Tuple <uint[][], UInt32[]> HistogramByteComponentsAndKeyArray <T>(T[] inArray, Int32 l, Int32 r, Func <T, UInt32> getKey)
        {
            const int numberOfBins   = 256;
            const int numberOfDigits = sizeof(UInt32);
            var       inKeys         = new UInt32[inArray.Length];
            var       count          = new uint[numberOfDigits][];

            for (int i = 0; i < numberOfDigits; i++)
            {
                count[i] = new uint[numberOfBins];
            }
#if true
            var union = new UInt32ByteUnion();
            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   = getKey(inArray[current]);
                inKeys[current] = union.integer;
                count[0][union.byte0]++;
                count[1][union.byte1]++;
                count[2][union.byte2]++;
                count[3][union.byte3]++;
            }
#else
            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
            {
                uint value = inArray[current];
                count[0][value & 0xff]++;
                count[1][(value & 0xff00) >> 8]++;
                count[2][(value & 0xff0000) >> 16]++;
                count[3][(value & 0xff000000) >> 24]++;
            }
#endif
            return(new Tuple <uint[][], UInt32[]>(count, inKeys));
        }
Пример #3
0
        public static uint[][] HistogramByteComponents <T>(T[] inArray, Int32 l, Int32 r, Func <T, UInt32> getKey)
        {
            const int numberOfBins   = 256;
            const int numberOfDigits = sizeof(UInt32);

            uint[][] count = new uint[numberOfDigits][];
            for (int i = 0; i < numberOfDigits; i++)
            {
                count[i] = new uint[numberOfBins];
            }
#if true
            var union = new UInt32ByteUnion();
            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 = getKey(inArray[current]);
                count[0][union.byte0]++;
                count[1][union.byte1]++;
                count[2][union.byte2]++;
                count[3][union.byte3]++;
            }
#else
            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
            {
                uint value = getKey(inArray[current]);
                count[0][(byte)value]++;
                count[1][(byte)(value >> 8)]++;
                count[2][(byte)(value >> 16)]++;
                count[3][(byte)(value >> 24)]++;
            }
#endif
            return(count);
        }
Пример #4
0
        public static uint[][][] HistogramByteComponentsAcrossWorkQuantas(uint[] inArray, uint workQuanta)
        {
            const int numberOfBins    = 256;
            const int numberOfDigits  = sizeof(uint);
            uint      numberOfQuantas = (inArray.Length % workQuanta) == 0 ? (uint)(inArray.Length / workQuanta) : (uint)(inArray.Length / workQuanta + 1);

            Console.WriteLine("Histogram: inArray.Length = {0}, workQuanta = {1}, numberOfQuantas = {2}", inArray.Length, workQuanta, numberOfQuantas);

            uint[][][] count = new uint[numberOfQuantas][][];          // count for each parallel work item
            for (int i = 0; i < numberOfQuantas; i++)
            {
                count[i] = new uint[numberOfDigits][];
                for (int d = 0; d < numberOfDigits; d++)
                {
                    count[i][d] = new uint[numberOfBins];
                }
            }

            uint numberOfFullQuantas = (uint)(inArray.Length / workQuanta);
            int  currIndex           = 0;
            var  union = new UInt32ByteUnion();
            uint q     = 0;

            for (; q < numberOfFullQuantas; q++)
            {
                for (uint j = 0; j < workQuanta; j++)
                {
                    union.integer = inArray[currIndex++];
                    count[q][0][union.byte0]++;
                    count[q][1][union.byte1]++;
                    count[q][2][union.byte2]++;
                    count[q][3][union.byte3]++;
                }
            }
            // Last work quanta may be a partial one, whenever array length doesn't divide evenly by work quanta
            for (; currIndex < inArray.Length;)    // Scan the array and count the number of times each digit value appears - i.e. size of each bin
            {
                union.integer = inArray[currIndex++];
                count[q][0][union.byte0]++;
                count[q][1][union.byte1]++;
                count[q][2][union.byte2]++;
                count[q][3][union.byte3]++;
            }

            for (int d = 0; d < numberOfDigits; d++)
            {
                for (q = 0; q < numberOfQuantas; q++)
                {
                    Console.WriteLine("h: q = {0}   d = {1}", q, d);
                    for (uint b = 0; b < numberOfBins; b++)
                    {
                        Console.Write("{0} ", count[q][d][b]);
                    }
                    Console.WriteLine();
                }
            }

            return(count);
        }
Пример #5
0
        private static uint[][] ByteCountInner(uint[] inArray, Int32 l, Int32 r, int numberOfDigits, int numberOfBins)
        {
            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             digits = new byte[4];
                UInt32ByteUnion union  = new UInt32ByteUnion();
                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]++;
                }
                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 = ByteCountInner(inArray, l, m, numberOfDigits, numberOfBins);
            },
                            () =>
            {
                countRight = ByteCountInner(inArray, m + 1, r, numberOfDigits, numberOfBins);
            }
                            );
            // 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);
        }
Пример #6
0
        // The idea of 1-D array is that the individual digit counts (256 per digit in case of 8-bit digits) don't interfere with each other in L1 cache
        // whereas with jagged array they may depending on how each row happens to be allocated on the heap
        public static uint[] HistogramByteComponents1D(uint[] inArray, Int32 l, Int32 r)
        {
            const int numberOfBins = 256;
            const int numberOfDigits = sizeof(uint);
            uint[] count = new uint[numberOfDigits * numberOfBins];

            var union = new UInt32ByteUnion();
            for (int current = l; current <= r; current++)
            {
                union.integer = inArray[current];
                count[      union.byte0]++;
                count[256 + union.byte1]++;
                count[512 + union.byte2]++;
                count[768 + union.byte3]++;
            }
            return count;
        }
Пример #7
0
        public static uint[][] HistogramNBitsPerComponents(uint[] inArray, Int32 l, Int32 r, int bitsPerComponent)
        {
            int numberOfBins   = 1 << bitsPerComponent;
            int numberOfDigits = (sizeof(uint) * 8 + bitsPerComponent - 1) / bitsPerComponent;  // round up

            //Console.WriteLine("HistogramNBitsPerComponents: NumberOfDigits = {0}", numberOfDigits);
            uint[][] countLeft = new uint[numberOfDigits][];
            for (int i = 0; i < numberOfDigits; i++)
            {
                countLeft[i] = new uint[numberOfBins];
            }
            if (bitsPerComponent == 8)
            {
                var union = new UInt32ByteUnion();
                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]++;
                }
            }
            else if (bitsPerComponent == 9)
            {
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    countLeft[0][value & 0x1ff]++;
                    countLeft[1][(value & 0x3fe00) >> 9]++;
                    countLeft[2][(value & 0x7fc0000) >> 18]++;
                    countLeft[3][(value & 0xf8000000) >> 27]++;
                }
            }
            else if (bitsPerComponent == 10)
            {
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    countLeft[0][value & 0x3ff]++;
                    countLeft[1][(value & 0xffc00) >> 10]++;
                    countLeft[2][(value & 0x3ff00000) >> 20]++;
                    countLeft[3][(value & 0xc0000000) >> 30]++;
                }
            }
            else if (bitsPerComponent == 11)
            {
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    countLeft[0][value & 0x7ff]++;
                    countLeft[1][(value & 0x3ff800) >> 11]++;
                    countLeft[2][(value & 0xffc00000) >> 22]++;
                }
            }
            else if (bitsPerComponent == 12)
            {
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    countLeft[0][value & 0xfff]++;
                    countLeft[1][(value & 0xfff000) >> 12]++;
                    countLeft[2][(value & 0xff000000) >> 24]++;
                }
            }
            else if (bitsPerComponent == 13)
            {
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    countLeft[0][value & 0x1fff]++;
                    countLeft[1][(value & 0x3ffe000) >> 13]++;
                    countLeft[2][(value & 0xfc000000) >> 26]++;
                }
            }
            else if (bitsPerComponent == 16)
            {
                var union = new UInt32UShortUnion();
                for (int current = l; current <= r; current++)
                {
                    union.integer = inArray[current];
                    countLeft[0][union.ushort0]++;
                    countLeft[1][union.ushort1]++;
                }
            }
            else
            {
                uint componentMask = (uint)numberOfBins - 1;
                for (int current = l; current <= r; current++)
                {
                    uint value = inArray[current];
                    for (int i = 0; i < numberOfDigits; i++)
                    {
                        countLeft[i][value & componentMask]++;
                        componentMask <<= bitsPerComponent;
                    }
                }
            }
            return(countLeft);
        }
Пример #8
0
        /// <summary>
        /// Sort an array of unsigned integers using Radix Sorting algorithm (least significant digit variation)
        /// </summary>
        /// <param name="inputArray"></param>
        /// <returns>array of unsigned integers</returns>
        public static uint[] SortRadixPar(this uint[] inputArray)
        {
            int numberOfBins          = 256;
            int numberOfDigits        = 4;
            int Log2ofPowerOfTwoRadix = 8;
            int d = 0;

            uint[] outputArray = new uint[inputArray.Length];

            uint[][] count = new uint[numberOfDigits][];
            for (int i = 0; i < numberOfDigits; i++)
            {
                count[i] = new uint[numberOfBins];
            }
            uint[][] startOfBin = new uint[numberOfDigits][];
            for (int i = 0; i < numberOfDigits; i++)
            {
                startOfBin[i] = new uint[numberOfBins];
            }
            bool outputArrayHasResult = false;

            uint bitMask          = 255;
            int  shiftRightAmount = 0;

            //Stopwatch stopwatch = new Stopwatch();
            //long frequency = Stopwatch.Frequency;
            ////Console.WriteLine("  Timer frequency in ticks per second = {0}", frequency);
            //long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;

            //stopwatch.Restart();
#if false
            var             digits = new byte[4];
            UInt32ByteUnion union  = new UInt32ByteUnion();
            for (uint current = 0; current < inputArray.Length; current++)    // Scan the array and count the number of times each digit value appears - i.e. size of each bin
            {
                union.integer = inputArray[current];
                count[0][union.byte0]++;
                count[1][union.byte1]++;
                count[2][union.byte2]++;
                count[3][union.byte3]++;
            }
#else
            count = ByteCountInner(inputArray, 0, inputArray.Length - 1, numberOfDigits, numberOfBins);
#endif
            //stopwatch.Stop();
            //double timeForCounting = stopwatch.ElapsedTicks * nanosecPerTick / 1000000000.0;
            //Console.WriteLine("Time for counting: {0}", timeForCounting);

            for (d = 0; d < numberOfDigits; d++)
            {
                startOfBin[d][0] = 0;
                for (uint i = 1; i < numberOfBins; i++)
                {
                    startOfBin[d][i] = startOfBin[d][i - 1] + count[d][i - 1];
                }
            }

            d = 0;
            while (bitMask != 0)    // end processing digits when all the mask bits have been processed and shifted out, leaving no bits set in the bitMask
            {
                //stopwatch.Restart();
                uint[] startOfBinLoc = startOfBin[d];
                for (uint current = 0; current < inputArray.Length; current++)
                {
                    //outputArray[startOfBinLoc[ExtractDigit(inputArray[current], bitMask, shiftRightAmount)]++] = inputArray[current];
                    outputArray[startOfBinLoc[(inputArray[current] & bitMask) >> shiftRightAmount]++] = inputArray[current];
                }
                //stopwatch.Stop();
                //double timeForPermuting = stopwatch.ElapsedTicks * nanosecPerTick / 1000000000.0;
                //Console.WriteLine("Time for permuting: {0}", timeForPermuting);

                bitMask            <<= Log2ofPowerOfTwoRadix;
                shiftRightAmount    += Log2ofPowerOfTwoRadix;
                outputArrayHasResult = !outputArrayHasResult;
                d++;

                uint[] tmp = inputArray;       // swap input and output arrays
                inputArray  = outputArray;
                outputArray = tmp;
            }
            if (outputArrayHasResult)
            {
                for (uint current = 0; current < inputArray.Length; current++)    // copy from output array into the input array
                {
                    inputArray[current] = outputArray[current];
                }
            }

            return(inputArray);
        }