int count = N / size;int remainder = N % size;int start, stop;if (rank < remainder) { // The first 'remainder' ranks get 'count + 1' tasks each start = rank * (count + 1); stop = start + count;} else { // The remaining 'size - remainder' ranks get 'count' task each start = rank * count + remainder; stop = start + (count - 1);}for (int i = start; i <= stop; ++i) { a[i] = DO_SOME_WORK(); } 它是这样工作的: /* # ranks: remainder size - remainder /------------------------------------\ /-----------------------------\ rank: 0 1 remainder-1 size-1 +---------+---------+-......-+---------+-------+-------+-.....-+-------+ tasks: | count+1 | count+1 | ...... | count+1 | count | count | ..... | count | +---------+---------+-......-+---------+-------+-------+-.....-+-------+ ^ ^ ^ ^ | | | | task #: rank * (count+1) | rank * count + remainder | | | task #: rank * (count+1) + count rank * count + remainder + count - 1 \------------------------------------/ # tasks: remainder * count + remainder*/ Hi all, I have an array of length N, and I'd like to divide it as best as possible between 'size' processors. N/size has a remainder, e.g. 1000 array elements divided by 7 processes, or 14 processes by 3 processes. I'm aware of at least a couple of ways of work sharing in MPI, such as:for (i=rank; i<N;i+=size){ a[i] = DO_SOME_WORK } However, this does not divide the array into contiguous chunks, which I'd like to do as I believe is faster for IO reasons.Another one I'm aware of is:int count = N / size;int start = rank * count;int stop = start + count;// now perform the loopint nloops = 0;for (int i=start; i<stop; ++i){ a[i] = DO_SOME_WORK;} However, with this method, for my first example we get 1000/7 = 142 = count. And so the last rank starts at 852 and ends at 994. The last 6 lines are ignored.Would be best solution to append something like this to the previous code?int remainder = N%size;int start = N-remainder; if (rank == 0){ for (i=start;i<N;i++){ a[i] = DO_SOME_WORK; }This seems messy, and if its the best solution I'm surprised I haven't seen it elsewhere.Thanks for any help! 解决方案 If I had N tasks (e.g., array elements) and size workers (e.g., MPI ranks), I would go as follows:int count = N / size;int remainder = N % size;int start, stop;if (rank < remainder) { // The first 'remainder' ranks get 'count + 1' tasks each start = rank * (count + 1); stop = start + count;} else { // The remaining 'size - remainder' ranks get 'count' task each start = rank * count + remainder; stop = start + (count - 1);}for (int i = start; i <= stop; ++i) { a[i] = DO_SOME_WORK(); }That is how it works:/* # ranks: remainder size - remainder /------------------------------------\ /-----------------------------\ rank: 0 1 remainder-1 size-1 +---------+---------+-......-+---------+-------+-------+-.....-+-------+ tasks: | count+1 | count+1 | ...... | count+1 | count | count | ..... | count | +---------+---------+-......-+---------+-------+-------+-.....-+-------+ ^ ^ ^ ^ | | | | task #: rank * (count+1) | rank * count + remainder | | | task #: rank * (count+1) + count rank * count + remainder + count - 1 \------------------------------------/ # tasks: remainder * count + remainder*/ 这篇关于尽管array_size不能被进程数完全分割,如何在MPI的进程之间大致均匀地共享工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-29 09:55