C# 如何对同一数组中的随机位置执行多线程操作?
我有一个进程在C# 如何对同一数组中的随机位置执行多线程操作?,c#,arrays,multithreading,random,parallel-processing,C#,Arrays,Multithreading,Random,Parallel Processing,我有一个进程在Array中的随机位置上运行大量任务,并希望通过使用多线程来加速这一进程 它基本上是将“数组”中的一个位置随机化,检查其周围的值,如果满足一些特定条件,则更改随机位置值 有可能运行类似于 Parallel.For(0, n, s => { }); 循环而不是下面所示的while代码块来优化这个函数,那么一个代码块是什么样子的呢 我一直在考虑对所选元素使用一些“忙”属性,但这实际上使问题变得更加复杂 public void doStuffTothisArray(ref int
Array
中的随机位置上运行大量任务,并希望通过使用多线程来加速这一进程
它基本上是将“数组”中的一个位置随机化,检查其周围的值,如果满足一些特定条件,则更改随机位置值
有可能运行类似于
Parallel.For(0, n, s => { });
循环而不是下面所示的while代码块来优化这个函数,那么一个代码块是什么样子的呢
我一直在考虑对所选元素使用一些“忙”属性,但这实际上使问题变得更加复杂
public void doStuffTothisArray(ref int[,,] Array, ref IGenerator randomGenerator, int loops)
{
int cc = 0;
int sw = 0;
do
{
if (doStuffOnRandomPositions(ref Array, ref randomGenerator))
sw++; //if stuff was made counter
if ((cc % (loops / 10)) == 0)
Console.Write("{0} % \t", (cc / (loops / 10)) * 10); //some loading info
cc++; //count iterations
} while (cc < loops);
Console.WriteLine("Stuff altered in {0} iterations: {1}", loops, sw);
}
public void dostuffttothisarray(ref int[,]数组,ref IGenerator randomGenerator,int循环)
{
int cc=0;
int-sw=0;
做
{
if(dostufforandompositions(参考数组,参考随机生成器))
sw++;//如果东西是用计数器制作的
如果((cc%(循环/10))==0)
Write(“{0}%\t”,(cc/(loops/10))*10);//一些加载信息
cc++;//计算迭代次数
}而(cc
后期编辑:
分割阵列并分配工作会破坏阵列的动态性,因为它需要是一个完整的系统
这是dostuff的原型…)
public static bool dostuffandompositions(参考晶格A,参考发电机rr)
{
position firstPos=新位置(rr.Next(0,A.n_大小)、rr.Next(0,A.n_大小)、rr.Next(0,A.n_大小));
位置secondPos=随机相邻位置(参考A、firstPos、参考rr);
//检查晶格中最近的3d邻居索引器
//Console.WriteLine(“第一:[{0},{1},{2}]\n第二:[{3},{4},{5}]\n”,第一位置x,第一位置y,第一位置z,第二位置x,第二位置y,第二位置z);
//获取坐标处的值
bool first=A.latticeArray[firstPos.x,firstPos.y,firstPos.z];
布尔秒=格子阵列[secondPos.x,secondPos.y,secondPos.z];
if(first==second)//如果它们是相等的状态,就不用麻烦了
返回false;
//检查周围环境的能量,以确定最终的自旋开关
int-surrBefore=surroundCheck(参考A,firstPos,first);//-surroundCheck(参考A,secondPos,second));
int-surrAfter=surroundCheck(参考A,firstPos,!first);//-surroundCheck(参考A,secondPos,!second));
if(surrAfter
在这种情况下,lattice类应该表示包含属性的“数组”。示例解决方案代码将非常感谢,因为我对c#方法有丰富的经验。如果您的操作的范围是非相交的元素范围(如1-10、25-40、100-123),那么您可以在单独的范围内运行操作,而不是并行运行单个元素。如果在操作进行期间不重新分配阵列,则不需要任何其他同步
如果操作更改了随机元素,则必须进行适当的同步,并且可能无法从在多个线程上运行代码中获得任何好处。鉴于您正在修改数组,这是共享状态,我看不出如何在不使用竞争条件的情况下对其进行优化。可能修改的索引是否基于RNG提供的选定索引确定?如果是这样,您可以构建同步,以防止在可能的修改可能重叠时出现并行性。只有当
dostufforrandompositions
足够复杂,足以保证额外的并行和同步开销时,这才有意义。为了避免竞争条件,您可以为每个项设置一个锁对象数组(或类似的同步)。这将取决于@Moho提到的对象的决定论,以及方法的复杂性。锁定这些多个对象也可能造成死锁。您必须设计锁定机制以避免这种情况。显示dostufforandompositions的代码
public static bool doStuffOnRandomPositions(ref lattice A, ref IGenerator rr)
{
position firstPos = new position(rr.Next(0, A.n_size),rr.Next(0, A.n_size),rr.Next(0, A.n_size));
position secondPos = randomNeighbour(ref A, firstPos, ref rr);
//checks the closest 3d neighbours indexer the lattice
//Console.WriteLine("first:[{0},{1},{2}]\nsecond:[{3},{4},{5}]\n", firstPos.x, firstPos.y, firstPos.z, secondPos.x, secondPos.y, secondPos.z);
// get values at coordinates
bool first = A.latticeArray[firstPos.x, firstPos.y, firstPos.z];
bool second = A.latticeArray[secondPos.x,secondPos.y,secondPos.z];
if (first == second) //don't bother if they are equal states
return false;
// checks the energies in surroundings for an eventual spin switch
int surrBefore = surroundCheck(ref A, firstPos, first) ; // - surroundCheck(ref A, secondPos, second));
int surrAfter = surroundCheck(ref A, firstPos, !first) ; // - surroundCheck(ref A, secondPos, !second));
if (surrAfter < surrBefore) //switch spin states if lower total energy
{
A.latticeArray[firstPos.x, firstPos.y, firstPos.z] = !first;
A.latticeArray[secondPos.x, secondPos.y, secondPos.z] = !second;
return true;
}
else if ((surrAfter == surrBefore) & latticeDistribution(ref rr)) //TEMPORARY
{
A.latticeArray[firstPos.x, firstPos.y, firstPos.z] = !first; //TEMPORARY
A.latticeArray[secondPos.x, secondPos.y, secondPos.z] = !second; //TEMPORARY
return true;
}
else
return false;
} //FIX SWITCH PROBABILITIES