как уменьшить движение данных для повышения производительности - PullRequest
1 голос
/ 14 мая 2019

Я пытаюсь улучшить производительность в коде Фортрана с помощью openACC, однако компилятор показывает, что между устройством и хостом происходит много передач

Я пытался использовать области данных для уменьшения движения памяти

Это часть кода, полная подпрограмма для решения уравнений с использованием LU

!EXCHANGING AND ELIMINATING COLUMNS

!$acc data copy(a(:,k:n))create(a(:,k:n))   
!$acc kernels

                                DO J = K + 1, N
                                        TQ = A(M, J)
                                        A(M, J) = A(K, J)
                                        A(K, J) = TQ

                                        IF (DABS(TQ) .GT. 0) THEN
                                        DO I = K + 1,N
                                                A(I,J)=A(I,J)+A(I,K)*TQ
                                        ENDDO
                                        END IF
                                ENDDO
!$acc end kernels
!$acc end data

Я ожидал сократить время вычислений, код работает без области данных, но очень медленно, и при использовании области данных программа останавливается из-за невозможного факторинга

1 Ответ

1 голос
/ 14 мая 2019

Области вычисления OpenACC, то есть "ядра" или "параллельные", включают в себя неявную область данных.Если он не находится в той же области, что и область структурированных данных, и без каких-либо предложений данных в области вычислений, компилятор будет неявно копировать данные для вас.Добавление области данных переопределит эти неявные данные и даст вам больше контроля над тем, когда данные передаются.

Ошибка, которую вы видите с областью данных, наиболее вероятна из-за того, что «а» в обоих «а»скопировать "и" создать "предложение.Поскольку переменные могут появляться только один раз, будет использоваться самое правое предложение (т. Е. Create), и, следовательно, ваши данные не копируются на устройство или с него.Чтобы исправить, удалите предложение создания.(Обратите внимание, что при копировании будут создаваться и копироваться)

Однако, поскольку у вас есть область данных непосредственно вокруг вычислительной области, ваша производительность останется неизменной.Чтобы помочь с этим, я бы посоветовал переместить область данных в более раннюю область кода, например, сразу после того, как «а» выделено или инициализировано.Затем добавьте предложение «present (a)» в директиву «kernels», чтобы обеспечить наличие данных на устройстве.

Чтобы обеспечить синхронизацию данных между хостом и устройством, используйте директивы «update» переди после вычислительной области.Следующий шаг - начать перемещение директив «update» наружу, одновременно загружая больше вычислений на устройство.В идеале вы должны разгрузить весь код, который работает с массивом «A», чтобы данные копировались на устройство один раз в начале программы и обратно на хост один раз, когда вам нужно напечатать результаты.

...