Я могу выслать свой код, если необходимо, но мой вопрос в основном концептуальный. Я реализую гауссово исключение с потоком. У меня есть p preads, работающие на матрице nxn в главном порядке столбца. Прежде чем какой-либо p-поток может начать работать в столбце, необходимо выполнить операции над строкой, чтобы переместить строку с наибольшим значением в этом столбце до диагонали. Поэтому мне нужен каждый поток, чтобы ждать, а затем работать в унисон. В настоящее время в каждом столбце каждый поток проверяет свой идентификатор, один с id = 0 будет выполнять операции над строкой. Моя проблема заключается в том, как получить все потоки, но id = 0, чтобы ждать, а затем работать в Unison.Pthread условные обозначения
Я пробовал использовать блокировки и условные обозначения мьютекса. Они не работают, потому что они дают все права доступа к одному потоку. Из того, что я понимаю, можно только блокировать поток таким образом, запросив блокировку, где она уже существует, поэтому она должна ждать. Это было бы проблемой в моем случае, потому что я не хочу, чтобы ни один из не-нитей имел блокировку, после того как они разблокированы, я хочу, чтобы они свободно работали, пока они не закончат работу над столбцом.
Я пытался избежать блокировок Mutex, просто имея глобальную переменную colReady, равную 0. Ненулевые нити while, пока colReady = True. Логически это имеет смысл, но он не работал программно.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <pthread.h>
#define n 20
#define numThr 3
double **matrix;
int pivotReady[n] = { 0 };
pthread_cond_t cond_pivot_ready;
pthread_mutex_t cond_mutex;
int swapRows (int row1, int row2)
{
double *tempRow = matrix[row1];
matrix[row1] = matrix[row2];
matrix[row2] = tempRow;
return 0;
}
void randinit()
{
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n + 1; j++) {
matrix[i][j] = drand48();
}
}
}
void rowReduce (void *arg);
void printMatrix()
{
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n + 1; j++) {
printf (" %4.2f ", matrix[i][j]);
}
printf ("\n");
}
}
int main()
{
pthread_cond_init (&cond_pivot_ready, NULL);
pthread_mutex_init (&cond_mutex, NULL);
int i, j;
double temp;
pthread_t p_threads[numThr];
pthread_attr_t attr;
pthread_attr_init (&attr);
//create matrix
matrix = malloc (sizeof (double *) * n);
for (i = 0; i < n; i++) {
*(matrix + i) = malloc (sizeof (double) * (n + 1));
}
randinit();
for (i = 0; i < numThr; i++) {
pthread_create (&p_threads[i], &attr, rowReduce, (void *) ((long) i));
}
for (i = 0; i < numThr; i++) {
pthread_join (p_threads[i], NULL);
}
printf ("Final Matrix:\n");
printMatrix();
return 0;
}
void rowReduce (void *arg)
{
int id = (int) arg;
int i, pivot, row;
double ratio, temp, max;
int maxRow;
for (pivot = 0; pivot < n - 1; pivot++) {
//PIVOT THREAD
if (id == 0) {
pthread_mutex_lock (&cond_mutex);
max = matrix[pivot][pivot]
maxRow = pivot;
for (i = pivot + 1; i < n; i++) {
temp = matrix[i][pivot];
if (temp > max) {
max = temp;
maxRow = i;
}
}
swapRows (pivot, maxRow);
pivotReady[pivot] = 1;
pthread_cond_signal (&cond_pivot_ready);
for (row = pivot + 1 + id; row < n; row += numThr) {
ratio = matrix[row][pivot]/matrix[pivot][pivot];
printf ("t1: row = %d, piv = %d, ratio = %f\n", row, pivot,
ratio);
for (int i = pivot; i < n + 1; i++) {
matrix[row][i] -= ratio * matrix[pivot][i];
}
}
pthread_mutex_unlock (&cond_mutex);
}
//NON-PIVOT THREAD
else {
pthread_mutex_lock (&cond_mutex);
while (!(pivotReady[pivot])) {
pthread_cond_wait (&cond_pivot_ready, &cond_mutex);
}
for (row = pivot + 1 + id; row < n; row += numThr) {
ratio = matrix[row][pivot]/matrix[pivot][pivot];
for (int i = pivot; i < n + 1; i++) {
matrix[row][i] -= ratio * matrix[pivot][i];
}
}
pthread_mutex_unlock (&cond_mutex);
}
}
//printf("rowReduce called with id = %d\n", id);
pthread_exit (0);
}
Эта программа ДОЛЖНА напечатать случайную матрицу, которая была помещена в верхнюю треугольную форму.
Вы должны смотреть на 'pthread_barrier_wait()'. – JS1
Примечание: если матрица HUUUGE (действительно огромная!), Попытка создания параллельной версии алгоритма не окупается. В более абстрактном виде: приложение, которое будет использовать это, вероятно, должно будет решить эту проблему много раз, и вам лучше запустить параллельные версии однопоточного алгоритма. Чтобы он полностью окупился, вам нужно было бы найти безошибочный подход к алгоритму. С другой стороны, использование параллелизма данных было бы хорошей идеей. Ключевое слово: SIMD. – BitTickler
Я не смотрел ваш код, но на основе вашего описания почему бы не основной поток сортировать строки, а затем запустить другие потоки после подготовки матрицы? –