Попытка распараллеливания, несмотря на зависимости данных ⇐ C++
Попытка распараллеливания, несмотря на зависимости данных
Я пытаюсь распараллелить умножение матриц. Я наткнулся на алгоритм Фокса, который может разбить все на 3 шага. Алгоритм можно посмотреть. Я прикрепил здесь описание изображения image.enter. Кодекс:
void matmul_fox(int *matrixA, int *matrixB, int *zeroMatrix, int n){ #pragma acc ядра copyin(matrixA[0:n*n],матрицаB[0:n*n]) copy(zeroMatrix[0:n*n]) { // Операция 1 #pragma независимая петля акк for (int i = 0; i < n; i++){ // Извлекаем диагональ из arr1 #pragma независимая петля акк for (int j = 0; j < n; j++){ // Добавляем arr3 и умножаем Diag(broadcasted)*arr2 #pragma acc независимое сокращение цикла (+: zeroMatrix[0:n*n]) for (int k = 0; k < n; k++){ нольMatrix[j * n + k] += матрица A[j * n + j] * матрица B[j * n + k]; } } // Операция 2 // Сдвиг вверх по строкам arr2 #pragma независимая петля акк for (int a = 0; a < n; a++) { int temp1 = матрицаB[0 * n + a]; #pragma независимая петля акк for (int j = 0; j < n - 1; j++) { матрицаB[j * n + a] = матрица B[(j + 1) * n + a]; } матрицаB[(n - 1) * n + a] = temp1; } // Операция 3 // Shift-влево по строкам arr1 #pragma независимая петля акк for (int b = 0; b < n; b++){ int temp2 = матрицаA[b * n + 0]; // Сохраняем первый элемент строки #pragma независимая петля акк for (int j = 0; j < n - 1; j++){ матрицаA[b * n + j] = матрицаA[b * n + (j+1)]; // Сдвигаем элементы влево } матрицаA[b * n + (n - 1)] = temp2; // Размещаем первый элемент в конце } } } } Поскольку операция 2 и операция 3 имеют зависимости, я не могу распараллелить эти три операции вместе. Однако я где-то читал, что для решения этой проблемы мы можем использовать такие предложения, как async, wait и update. Возможно, Операция 2 и Операция 3 могут подождать, пока не завершится Операция 1, а как только она будет завершена, Операция 2 и Операция 3 могут выполняться параллельно, поскольку между ними нет зависимостей.
Я пробовал без использования предложений ожидания, но, поскольку есть видимые зависимости, это дает неверный результат. Без использования OpenACC код работает корректно, но время выполнения больше, чем у традиционного последовательного алгоритма. Если алгоритм Фокса сможет работать параллельно, я могу ожидать более высокой производительности.
Я пытаюсь распараллелить умножение матриц. Я наткнулся на алгоритм Фокса, который может разбить все на 3 шага. Алгоритм можно посмотреть. Я прикрепил здесь описание изображения image.enter. Кодекс:
void matmul_fox(int *matrixA, int *matrixB, int *zeroMatrix, int n){ #pragma acc ядра copyin(matrixA[0:n*n],матрицаB[0:n*n]) copy(zeroMatrix[0:n*n]) { // Операция 1 #pragma независимая петля акк for (int i = 0; i < n; i++){ // Извлекаем диагональ из arr1 #pragma независимая петля акк for (int j = 0; j < n; j++){ // Добавляем arr3 и умножаем Diag(broadcasted)*arr2 #pragma acc независимое сокращение цикла (+: zeroMatrix[0:n*n]) for (int k = 0; k < n; k++){ нольMatrix[j * n + k] += матрица A[j * n + j] * матрица B[j * n + k]; } } // Операция 2 // Сдвиг вверх по строкам arr2 #pragma независимая петля акк for (int a = 0; a < n; a++) { int temp1 = матрицаB[0 * n + a]; #pragma независимая петля акк for (int j = 0; j < n - 1; j++) { матрицаB[j * n + a] = матрица B[(j + 1) * n + a]; } матрицаB[(n - 1) * n + a] = temp1; } // Операция 3 // Shift-влево по строкам arr1 #pragma независимая петля акк for (int b = 0; b < n; b++){ int temp2 = матрицаA[b * n + 0]; // Сохраняем первый элемент строки #pragma независимая петля акк for (int j = 0; j < n - 1; j++){ матрицаA[b * n + j] = матрицаA[b * n + (j+1)]; // Сдвигаем элементы влево } матрицаA[b * n + (n - 1)] = temp2; // Размещаем первый элемент в конце } } } } Поскольку операция 2 и операция 3 имеют зависимости, я не могу распараллелить эти три операции вместе. Однако я где-то читал, что для решения этой проблемы мы можем использовать такие предложения, как async, wait и update. Возможно, Операция 2 и Операция 3 могут подождать, пока не завершится Операция 1, а как только она будет завершена, Операция 2 и Операция 3 могут выполняться параллельно, поскольку между ними нет зависимостей.
Я пробовал без использования предложений ожидания, но, поскольку есть видимые зависимости, это дает неверный результат. Без использования OpenACC код работает корректно, но время выполнения больше, чем у традиционного последовательного алгоритма. Если алгоритм Фокса сможет работать параллельно, я могу ожидать более высокой производительности.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Невозможно выбрать объекты protobuf для распараллеливания с использованием луча в Python
Anonymous » » в форуме Python - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-