現在、特定の数のスレッドを使用して2つの行列を乗算しようとしています。ユーザー設定のスレッド数を使用した行列の乗算
私は最近同じタスク(old approach)に関連する投稿を公開しましたが、今ではこの課題を解決するための戦略を変更しました。
私はもはやスレッドプールを使用していません。代わりに、自分でスレッドを管理しています。
これは私の現在のソリューションである:
class Matrix
{
// Stores a random generator
Random rnd = new Random();
int[,] map = new int[16, 16];
// Stores the cell which have to be processed
static List<Cell> TaskList = new List<Cell>();
// Stores the threads used for processing
static List<Thread> Threads = new List<Thread>();
// Stores the result matrix
static Matrix c = new Matrix();
// Fill a matrix with an given value
public void fillMatrixWithValue(int val)
{
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
map[i, j] = val;
}
}
}
// Fill a matrix with random values
public void fillMatrixWithRandomValues(int range = 10)
{
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
map[i, j] = getRandomNumber(range);
}
}
}
// Return a random number for random matrix generation
int getRandomNumber(int range)
{
return rnd.Next(1, range);
}
// Print a matrix to console
public void printMatrix()
{
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
Console.Write(map[i, j] + " ");
}
Console.WriteLine();
}
Console.WriteLine();
}
// Calculate the result matrix sequential
public static Matrix MultiplyMatricesSequential(Matrix a, Matrix b)
{
Matrix c = new Matrix();
for (int row = 0; row < a.map.GetLength(0); row++)
{
for (int col = 0; col < a.map.GetLength(1); col++)
{
for (int i = 0; i < a.map.GetLength(0); i++)
{
c.map[row, col] += a.map[row, i] * b.map[i, col];
}
}
}
return c;
}
// Calculate the result matrix parallel via threads
public static Matrix MultiplyMatricesAsynchronous(Matrix a, Matrix b, int amountOfThreads)
{
// Stores the row values needed for calculation of the result cell value
int[] row = new int[a.map.GetLength(0)];
// Stores the col values needed for calculation of the result cell value
int[] col = new int[a.map.GetLength(1)];
// Store the position indizes of the result cell
int x = 0, y = 0;
// Calculate and store the cell information used for calculation of the result value
for (int i = 0; i < a.map.GetLength(0); i++)
{
for (int j = 0; j < a.map.GetLength(1); j++)
{
for (int k = 0; k < a.map.GetLength(0); k++)
{
row[k] = a.map[i, k];
col[k] = b.map[k, j];
x = i;
y = j;
}
TaskList.Add(new Cell(row, col, x, y));
}
}
// Get the intial amount of threads (created by OS)
int amountOfInitialThreads = Process.GetCurrentProcess().Threads.Count;
// Run till all cells have been processed
do
{
// Only create a new thread if thread limit (user input) has not been reached yet
if (Process.GetCurrentProcess().Threads.Count < (amountOfInitialThreads + amountOfThreads))
{
Thread temp = new Thread(new ThreadStart(calculateCell));
Threads.Add(temp);
temp.Start();
}
foreach (Thread t in Threads)
{
t.Join();
}
} while (TaskList.Count > 0);
return c;
}
// Calculate and set the result value in the result matrix
static void calculateCell()
{
Cell cell = null;
if (TaskList.Count != 0)
{
// Lock the list so that threads do not take the same cell for processing
lock (TaskList)
{
cell = TaskList[TaskList.Count - 1];
TaskList.RemoveAt(TaskList.Count - 1);
}
int temp = 0;
// Calculate and set the result cell value
for (int i = 0; i < cell.row.Length; i++)
{
temp = i;
c.map[cell.x, cell.y] += cell.row[temp] * cell.col[temp];
}
}
}
}
}
Iは、結果行列値の位置と結果値の計算に必要なベースマトリックスの行と列の値を格納するセルクラスを実装しています。
問題は、結果行列の各セルが同じ値で埋められるということです。
私が理解できないことは、各スレッドは正しいx値とy値を取得しますが、間違った行とcol値(各スレッドは同じ行とcol値をとります)です。いくつかの値が何らかの形でスレッド間で共有されていて、そうでないものがあります。
私はまだ多くのデバッグを行っていますが、私が間違っていることを理解できません。
誰でもできるのですか?
のための配列の新しいセットを取得するには「J」ループ内の配列宣言を移動する必要があります内部のi、jループ?同じ行(およびcol)配列をn回設定しています。問題はそこにあるようだ – tede24