2014-11-11 3 views
0

Возьмут следующий код, который иллюстрирует призвание простой рутины на ускорителе, составленный на устройстве с помощью OpenACC 2.0 в routine директиву:OpenACC 2,0 рутина: данные местонахождение

#include <iostream> 

#pragma acc routine 
int function(int *ARRAY,int multiplier){ 
     int sum=0; 

     #pragma acc loop reduction(+:sum) 
     for(int i=0; i<10; ++i){ 
       sum+=multiplier*ARRAY[i]; 
     } 

     return sum; 
} 

int main(){ 
     int *ARRAY = new int[10]; 
     int multiplier = 5; 
     int out; 

     for(int i=0; i<10; i++){ 
       ARRAY[i] = 1; 
     } 

     #pragma acc enter data create(out) copyin(ARRAY[0:10],multiplier) 

     #pragma acc parallel present(out,ARRAY[0:10],multiplier) 
     if (function(ARRAY,multiplier) == 50){ 
       out = 1; 
     }else{ 
       out = 0; 
     } 

     #pragma acc exit data copyout(out) delete(ARRAY[0:10],multiplier) 

     std::cout << out << std::endl; 
} 

Как function знать, чтобы использовать копии устройства ARRAY[0:10] и multiplier, когда он вызывается из параллельной области? Как мы можем обеспечить использование экземпляров устройства?

ответ

0

В принципе, когда вы включаете предложение «данные», устройство будет создавать/копировать данные в память устройства, тогда на устройстве будет выполнен блок кода, который определен с помощью процедуры «acc». Обратите внимание, что память между хостом и устройством не распространяется в отличие от многопоточности (OpenMP). Так что да, «функция» будет использовать копии устройства ARRAY и множителя, если он находится в сегменте данных. Надеюсь это поможет! :)

0

Вы должны назначить функцию с одним уровнем параллелизма, таким как банда/работник/вектор. Это более точный способ.

Подпрограмма будет использовать дату в памяти устройства.

1

Когда ваша процедура вызывается внутри области устройства (parallel в вашем коде), она вызывается потоками на устройстве, что означает, что эти потоки будут иметь доступ только к массивам на устройстве. Компилятор может фактически выбрать встроенную функцию, или это может быть вызов функции на стороне устройства. Это означает, что вы можете знать, что при вызове функции с устройства он будет получать копии экземпляров устройства, поскольку функция по существу наследует предложение данных present из параллельной области. Если вы все еще хотите убедить себя, что вы работаете на устройстве один раз внутри функции, вы можете позвонить acc_on_device, но это только говорит вам, что вы используете ускоритель, а не то, что вы получили указатель на устройство.

Если вы хотите, чтобы использование копий устройства было больше, вы могли бы сделать процедуру nohost так, чтобы она была технически недействительной для вызова с хоста, но на самом деле это не делает то, что вы просите , который должен проверить на GPU, что массив действительно является массивом устройств.

Имейте в виду, хотя, что любой код внутри параллельной области, которая не находится внутри loop будет работать групповому избыточно, поэтому запись в out, скорее всего, состояние гонки, если не случится быть запущен с одной бандой или вы пишете ему, используя atomic.

Смежные вопросы