Example #1
0
        public static void For(int start, int end, int chunkSize, ForDelegate action)
        {
            object oLock = new object();

            ProcessDelegate process = delegate() {
                for (int n = 0; n < end;)
                {
                    lock (oLock) {
                        n      = start;
                        start += chunkSize;
                    }

                    for (int k = 0; k < chunkSize && n < end; k++, n++)
                    {
                        action(n);
                    }
                }
            };

            int threads = Environment.ProcessorCount;

            WaitHandle[] handles = new WaitHandle[threads];
            for (int i = 0; i < threads; i++)
            {
                handles[i] = process.BeginInvoke(ProcessCallback, process).AsyncWaitHandle;
            }
            WaitHandle.WaitAll(handles);
        }
Example #2
0
 public static void For(int _x, int _y, ForDelegate _code)
 {
     for (int x = 0; x < _x; x++)
     {
         for (int y = 0; y < _y; y++)
         {
             _code(x, y);
         }
     }
 }
Example #3
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        public static void For(int fromInclusive, int toExclusive, ForDelegate forDelegate)
        {
            // chunkSize = 1 makes items to be processed in order.
            // Bigger chunk size should reduce lock waiting time and thus
            // increase paralelism.
            int chunkSize = 4;

            // number of process() threads
            int threadCount = Environment.ProcessorCount;
            int index       = fromInclusive - chunkSize;
            // locker object shared by all the process() delegates
            object locker = new object();

            // processing function
            // takes next chunk and processes it using action
            DelegateProcess process = delegate()
            {
                while (true)
                {
                    int chunkStart = 0;
                    lock (locker)
                    {
                        // take next chunk
                        index     += chunkSize;
                        chunkStart = index;
                    }
                    // process the chunk
                    // (another thread is processing another chunk
                    //  so the real order of items will be out-of-order)
                    for (int i = chunkStart; i < chunkStart + chunkSize; i++)
                    {
                        if (i >= toExclusive)
                        {
                            return;
                        }
                        forDelegate(i);
                    }
                }
            };

            // launch process() threads
            IAsyncResult[] asyncResults = new IAsyncResult[threadCount];
            for (int i = 0; i < threadCount; ++i)
            {
                asyncResults[i] = process.BeginInvoke(null, null);
            }
            // wait for all threads to complete
            for (int i = 0; i < threadCount; ++i)
            {
                process.EndInvoke(asyncResults[i]);
            }
        }
Example #4
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        /// <remarks>Source: http://coding-time.blogspot.com/2008/03/implement-your-own-parallelfor-in-c.html</remarks>
        public static void For(int fromInclusive, int toExclusive, ForDelegate action)
        {
            // ChunkSize = 1 makes items to be processed in order.
            // Bigger chunk size should reduce lock waiting time and thus
            // increase paralelism.
            int chunkSize = 4;

            // number of process() threads
            int threadCount = Environment.ProcessorCount;
            int cnt         = fromInclusive - chunkSize;

            // processing function
            // takes next chunk and processes it using action
            ThreadDelegate process = delegate()
            {
                while (true)
                {
                    int cntMem = 0;
                    lock (typeof(Parallel))
                    {
                        // take next chunk
                        cnt   += chunkSize;
                        cntMem = cnt;
                    }
                    // process chunk
                    // here items can come out of order if chunkSize > 1
                    for (int i = cntMem; i < cntMem + chunkSize; ++i)
                    {
                        if (i >= toExclusive)
                        {
                            return;
                        }
                        action(i);
                    }
                }
            };

            // launch process() threads
            IAsyncResult[] asyncResults = new IAsyncResult[threadCount];
            for (int i = 0; i < threadCount; ++i)
            {
                asyncResults[i] = process.BeginInvoke(null, null);
            }
            // wait for all threads to complete
            for (int i = 0; i < threadCount; ++i)
            {
                process.EndInvoke(asyncResults[i]);
            }
        }
Example #5
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        public static void For( int fromInclusive, int toExclusive, ForDelegate action )
        {
            // ChunkSize = 1 makes items to be processed in order.
            // Bigger chunk size should reduce lock waiting time and thus
            // increase paralelism.
            int chunkSize = 4;

            // number of process() threads
            int threadCount = Environment.ProcessorCount;
            int cnt = fromInclusive - chunkSize;

            // processing function
            // takes next chunk and processes it using action
            ThreadDelegate process = delegate()
            {
                while( true )
                {
                    int cntMem = 0;
                    lock( typeof( ParallelUtils ) )
                    {
                        // take next chunk
                        cnt += chunkSize;
                        cntMem = cnt;
                    }
                    // process chunk
                    // here items can come out of order if chunkSize > 1
                    for( int i = cntMem; i < cntMem + chunkSize; ++i )
                    {
                        if( i >= toExclusive ) return;
                        action( i );
                    }
                }
            };

            // launch process() threads
            IAsyncResult[] asyncResults = new IAsyncResult[ threadCount ];
            for( int i = 0; i < threadCount; ++i )
            {
                asyncResults[ i ] = process.BeginInvoke( null, null );
            }
            // wait for all threads to complete
            for( int i = 0; i < threadCount; ++i )
            {
                process.EndInvoke( asyncResults[ i ] );
            }
        }
Example #6
0
        public static void ForMethod()
        {
            //一, 其中,取数组里的元素使用如下的指令流程:
            // l 首先, 加载数组指针到堆栈: methodIL.Emit(OpCodes.Ldarg_0);
            // 2 然后, 加载现在要加载的元素在数组中的索引:methodIL.Emit(OpCodes.Ldloc_1);
            // 3 最后,获得数组中的元素:methodIL.Emit(OpCodes.Ldelem_I4); 这里的Ldelem_I4表示加载的数组元素为Int32类型。

            //  二, 取数组的长度使用下面这样的指令流程:
            // l 首先, 加载数组指针到堆栈: methodIL.Emit(OpCodes.Ldarg_0);
            // 2 然后, 加载数组的长度:methodIL.Emit(OpCodes.Ldlen);
            // 3 最后,由于加载的数组长度为无符号整数,所以还需要转换成Int32类型来使用:methodIL.Emit(OpCodes.Conv_I4);

            //定义一个传入参数为Int32[],返回值为INT32的方法
            DynamicMethod forMethod    = new DynamicMethod("ForRun", typeof(Int32), new Type[] { typeof(Int32[]) });
            ILGenerator   forGenerator = forMethod.GetILGenerator();
            //用来保存求和结果的局部变量
            LocalBuilder sum = forGenerator.DeclareLocal(typeof(Int32));
            //循环中使用的局部变量
            LocalBuilder i = forGenerator.DeclareLocal(typeof(Int32));

            Label compareLabel   = forGenerator.DefineLabel();
            Label enterLoopLabel = forGenerator.DefineLabel();

            //int sum = 0;
            forGenerator.Emit(OpCodes.Ldc_I4_0);
            forGenerator.Emit(OpCodes.Stloc_0);
            //int i = 0
            forGenerator.Emit(OpCodes.Ldc_I4_0);
            forGenerator.Emit(OpCodes.Stloc_1);
            forGenerator.Emit(OpCodes.Br, compareLabel);

            //定义一个标签,表示从下面开始进入循环体
            forGenerator.MarkLabel(enterLoopLabel);
            //sum += ints[i];
            //其中Ldelem_I4用来加载一个数组中的Int32类型的元素
            forGenerator.Emit(OpCodes.Ldloc_0);
            forGenerator.Emit(OpCodes.Ldarg_0);
            forGenerator.Emit(OpCodes.Ldloc_1);
            forGenerator.Emit(OpCodes.Ldelem_I4);
            forGenerator.Emit(OpCodes.Add);
            forGenerator.Emit(OpCodes.Stloc_0);
            //i++
            forGenerator.Emit(OpCodes.Ldloc_1);
            forGenerator.Emit(OpCodes.Ldc_I4_1);
            forGenerator.Emit(OpCodes.Add);
            forGenerator.Emit(OpCodes.Stloc_1);

            //定义一个标签,表示从下面开始进入循环的比较
            forGenerator.MarkLabel(compareLabel);
            //i < ints.Length
            forGenerator.Emit(OpCodes.Ldloc_1);
            forGenerator.Emit(OpCodes.Ldarg_0);
            forGenerator.Emit(OpCodes.Ldlen);
            forGenerator.Emit(OpCodes.Conv_I4);
            forGenerator.Emit(OpCodes.Clt);
            forGenerator.Emit(OpCodes.Brtrue_S, enterLoopLabel);

            //return sum;
            forGenerator.Emit(OpCodes.Ldloc_0);
            forGenerator.Emit(OpCodes.Ret);

            //完成动态方法的创建,并且获取一个可以执行该动态方法的委托
            ForDelegate forRun = (ForDelegate)forMethod.CreateDelegate(typeof(ForDelegate));

            // 执行动态方法,将在屏幕上打印Hello World!
            int result = forRun(new int[] { 1, 2, 3, 4, 5 });

            Console.WriteLine(result.ToString());
        }
Example #7
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        /// <param name="chunkSize">
        /// chunkSize = 1 makes items to be processed in order.
        /// Bigger chunk size should reduce lock waiting time and thus
        /// increase paralelism.
        /// </param>
        /// <param name="threadCount">number of process() threads</param>
        public static void For(int fromInclusive, int toExclusive, int chunkSize, int threadCount, ForDelegate forDelegate)
        {
            int index = fromInclusive - chunkSize;
            // locker object shared by all the process() delegates
            object locker = new object();

            // processing function
            // takes next chunk and processes it using action
            DelegateProcess process = delegate()
            {
                while (true)
                {
                    int chunkStart = 0;
                    lock (locker)
                    {
                        // take next chunk
                        index     += chunkSize;
                        chunkStart = index;
                    }
                    // process the chunk
                    // (another thread is processing another chunk
                    //  so the real order of items will be out-of-order)
                    for (int i = chunkStart; i < chunkStart + chunkSize; i++)
                    {
                        if (i >= toExclusive)
                        {
                            return;
                        }
                        forDelegate(i);
                    }
                }
            };

            // launch process() threads
            IAsyncResult[] asyncResults = new IAsyncResult[threadCount];
            for (int i = 0; i < threadCount; ++i)
            {
                asyncResults[i] = process.BeginInvoke(null, null);
            }
            // wait for all threads to complete
            for (int i = 0; i < threadCount; ++i)
            {
                process.EndInvoke(asyncResults[i]);
            }
        }
Example #8
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        /// <param name="chunkSize">
        /// chunkSize = 1 makes items to be processed in order.
        /// Bigger chunk size should reduce lock waiting time and thus
        /// increase paralelism.
        /// </param>
        public static void For(int fromInclusive, int toExclusive, int chunkSize, ForDelegate forDelegate)
        {
            int threadCount = System.Environment.ProcessorCount;

            For(fromInclusive, toExclusive, chunkSize, threadCount, forDelegate);
        }
Example #9
0
        /// <summary>
        /// Parallel for loop. Invokes given action, passing arguments
        /// fromInclusive - toExclusive on multiple threads.
        /// Returns when loop finished.
        /// </summary>
        public static void For(int fromInclusive, int toExclusive, ForDelegate forDelegate)
        {
            int chunkSize = 4;

            For(fromInclusive, toExclusive, chunkSize, forDelegate);
        }
Example #10
0
 public static void For(int start, int end, ForDelegate action)
 {
     For(start, end, 4, action);
 }