Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 二维阵列的并行分布_C#_Parallel Processing_Task Parallel Library_Multidimensional Array - Fatal编程技术网

C# 二维阵列的并行分布

C# 二维阵列的并行分布,c#,parallel-processing,task-parallel-library,multidimensional-array,C#,Parallel Processing,Task Parallel Library,Multidimensional Array,我需要一些关于并行工作负载分配的建议,基于热分布问题,使用Jocobi方法。该程序通过并行for-then将2D阵列拆分为4个大小相等的网格,然后将每个较小的网格进一步分解为行簇,例如10行,这些行将在新任务中处理。初始网格大小为10000x1000 该程序可以工作,但它比我的其他并行实现(例如,在不拆分2D数组的情况下对行进行集群)要慢得多。即使使用for循环,也会有很多延迟。我不明白为什么,因为阵列的访问时间。例如,计算:x[50009999]y[50009999](右下角) 有人能解释这次

我需要一些关于并行工作负载分配的建议,基于热分布问题,使用Jocobi方法。该程序通过并行for-then将2D阵列拆分为4个大小相等的网格,然后将每个较小的网格进一步分解为行簇,例如10行,这些行将在新任务中处理。初始网格大小为10000x1000

该程序可以工作,但它比我的其他并行实现(例如,在不拆分2D数组的情况下对行进行集群)要慢得多。即使使用for循环,也会有很多延迟。我不明白为什么,因为阵列的访问时间。例如,计算:x[50009999]y[50009999](右下角)

有人能解释这次抢劫的原因吗

class ParallelHeatDistribution_QuadCluster
{
    private double[,] heatGrid;
    private int gridDimensions;

    private int x1, x2, x3;
    private int y1, y2, y3;

    private int[,] quadDimensions;

    public ParallelHeatDistribution_QuadCluster(double[,] heatGrid, int gridDimensions)
    {
        this.heatGrid = heatGrid;
        this.gridDimensions = gridDimensions;

        this.x1 = 1;
        this.x2 = this.gridDimensions / 2;

        this.y1 = 1;
        this.y2 = this.gridDimensions / 2;

        this.x3 = this.gridDimensions - 1;
        this.y3 = this.gridDimensions - 1;

        this.quadDimensions = new int[4, 4] {{x1, x2, y1, y2}, {x1, x2, y2, y3}, {x2, x3, y1, y2}, {x2, x3, y2, y3}};
    }

    /// <summary>
    /// Start parallel distribution
    /// </summary>
    public void parallelDistribution(int clusterRowCount)
    {
        for (int i = 0; i < 1; i++)
        {
            DistributeWorkload(clusterRowCount, quadDimensions[3, 0], quadDimensions[3, 1], quadDimensions[3, 2], quadDimensions[3, 3]);
        }

        Parallel.For(0, 3, i =>
        {
            //DistributeWorkload(clusterRowCount, quadDimensions[i, 0], quadDimensions[i, 1], quadDimensions[i, 2], quadDimensions[i, 3]);
        });
    }

    /// <summary>
    /// Calculate heat distribution in parallel by assigning work to tasks based on x-amount of loop iterations.  Each iteration represents an array row partition
    /// </summary>
    private void DistributeWorkload(int clusterRowCount, int xStartPoint, int xEndpoint, int yStartPoint, int yEndpoint)
    {
        /* calculate data partition cluster for parallel distribution. */
        int clusterCount = (gridDimensions) / clusterRowCount;

        /* Parallel task arrays for black and white elements */
        Task[] taskArray1 = new Task[clusterCount];
        Task[] taskArray2 = new Task[clusterCount];

        try
        {
            /* assign work to for set of tasks calculating the "black squares" */
            int c = 0;
            for (int x1 = 0; x1 < clusterCount; x1++)
            {
                int clusterSize = c;
                taskArray1[x1] = new Task(() => setTask(clusterRowCount, clusterSize, true, xStartPoint, xEndpoint, yStartPoint, yEndpoint));
                c = c + clusterRowCount;
            }

            /* assign work to second set of tasks calculating the "white squares" */
            c = 0;
            for (int x2 = 0; x2 < clusterCount; x2++)
            {
                int clusterSize = c;
                taskArray2[x2] = new Task(() => setTask(clusterRowCount, clusterSize, false, xStartPoint, xEndpoint, yStartPoint, yEndpoint));
                c = c + clusterRowCount;
            }


            /* start all tasks */
            foreach (Task t in taskArray1) t.Start();
            Task.WaitAll(taskArray1);

            foreach (Task t in taskArray2) t.Start();
            /* and wait... */
            Task.WaitAll(taskArray2);

        }
        catch (AggregateException e)
        {
            Console.Write(e);
        }
    }

    /// <summary>
    /// Task: calculate a cluster of rows
    /// </summary>
    /// <param name="y"> y-axis position </param>
    /// <param name="isFirst"> determine grid element set </param>
    public void setTask(int clusterRowCount, int currentClusterCount, bool isFirst, int xStartPoint, int xEndpoint, int yStartPoint, int yEndpoint)
    {
        int yPos = yStartPoint + currentClusterCount;
        double temperature;

        for (int y = yPos; y < yEndpoint; y++)
        {
            for (int x = xStartPoint; x < xEndpoint; x++)
            {
                if (isFirst && y % 2 == 0 || !isFirst && y % 2 != 0)
                {
                    if (x % 2 == 0)
                    {
                        temperature = (heatGrid[y - 1, x] + heatGrid[y + 1, x] + heatGrid[y, x - 1] + heatGrid[y, x + 1]) / 4;
                        heatGrid[x, y] = temperature;
                    }
                }
                else
                {
                    if (x % 2 != 0)
                    {
                        temperature = (heatGrid[y - 1, x] + heatGrid[y + 1, x] + heatGrid[y, x - 1] + heatGrid[y, x + 1]) / 4;
                        heatGrid[x, y] = temperature;
                    }
                }
            }
        }
    }
}
类并行热分布
{
私人双[,]热网;
私有整数维;
专用int x1、x2、x3;
私人int y1、y2、y3;
私有整数[,]四维;
公共并行热分布(双[,]热网格,整数网格维度)
{
this.heatGrid=heatGrid;
this.gridDimensions=gridDimensions;
这是1.x1=1;
this.x2=this.gridDimensions/2;
这是1.y1=1;
this.y2=this.gridDimensions/2;
this.x3=this.gridDimensions-1;
this.y3=this.gridDimensions-1;
this.quadDimensions=新的int[4,4]{x1,x2,y1,y2},{x1,x2,y2,y3},{x2,x3,y1,y2},{x2,x3,y2,y3};
}
/// 
///启动并行分发
/// 
公共分布(int clusterRowCount)
{
对于(int i=0;i<1;i++)
{
分布式工作负载(clusterRowCount,quadDimensions[3,0],quadDimensions[3,1],quadDimensions[3,2],quadDimensions[3,3]);
}
对于(0,3,i=>
{
//分布式工作负载(clusterRowCount,quadDimensions[i,0],quadDimensions[i,1],quadDimensions[i,2],quadDimensions[i,3]);
});
}
/// 
///通过根据循环迭代的x数量将功分配给任务,并行计算热量分布。每个迭代代表一个数组行分区
/// 
私有void DistributeWorkload(int-clusterRowCount、int-xStartPoint、int-xEndpoint、int-yStartPoint、int-yEndpoint)
{
/*计算并行分发的数据分区群集*/
int clusterCount=(gridDimensions)/clusterRowCount;
/*黑白元素的并行任务阵列*/
Task[]taskArray1=新任务[clusterCount];
Task[]taskArray2=新任务[clusterCount];
尝试
{
/*为计算“黑色方块”的任务集分配工作*/
int c=0;
对于(int-x1=0;x1setTask(clusterRowCount、clusterSize、true、xStartPoint、xEndpoint、yStartPoint、yEndpoint));
c=c+集群行数;
}
/*将工作分配给第二组任务,计算“白色方块”*/
c=0;
对于(int x2=0;x2setTask(clusterRowCount、clusterSize、false、xStartPoint、xEndpoint、yStartPoint、yEndpoint));
c=c+集群行数;
}
/*启动所有任务*/
foreach(taskArray1中的任务t)t.Start();
Task.WaitAll(taskArray1);
foreach(taskArray2中的任务t)t.Start();
/*等等*/
Task.WaitAll(taskArray2);
}
捕获(聚合异常e)
{
控制台。写入(e);
}
}
/// 
///任务:计算一组行
/// 
///y轴位置
///确定网格元素集
公共void setTask(int-clusterRowCount、int-currentClusterCount、bool-isFirst、int-xStartPoint、int-xEndpoint、int-yStartPoint、int-yEndpoint)
{
int yPos=yStartPoint+currentClusterCount;
双温;
对于(int y=yPos;y
您的计算机有多少个CPU核心?如果是4(或更少),那么就没有理由在
Parallel.for()中使用
任务
s。。。我在mo使用i3,但最终将在8核机器上运行。