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); }
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); } } }
/// <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]); } }
/// <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]); } }
/// <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 ] ); } }
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()); }
/// <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]); } }
/// <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); }
/// <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); }
public static void For(int start, int end, ForDelegate action) { For(start, end, 4, action); }