Массив частных указателей на разделяемый массив в UPC
Я программирую в UPC, и у меня есть массив, разделенный между двумя потоками. Каждый поток имеет частные указатели на эти общие области:
#define SIZE 10000
#define HALFSIZE (SIZE/2)
shared [ HALFSIZE ] int table [ SIZE ]; /* all areas */
shared [ HALFSIZE ] int *first_area_pt; /* points to first thread area */
shared [ HALFSIZE ] int *second_area_pt; /* points to second thread area */
Теперь я хочу не 2, а N потоков, N областей и N указателей. Итак, мне нужен массив этих указателей:
shared [ HALFSIZE ] int *first_area_pt;
shared [ HALFSIZE ] int *second_area_pt;
Как мне это определить?
2 ответа
Поскольку нотация, которую вы используете, является нестандартной (хотя я понимаю, что она соответствует спецификации UPC - Unified Parallel C -), мы можем только догадываться, что вам может понадобиться. Было бы полезно выделить то, что вы используете, потому что (когда) это необычно.
Это выглядит внешне правдоподобно, при одной возможной интерпретации shared [ N ]
нотации.
#define SIZE 10000
#define NUMTHREADS 25
#define FRACSIZE (SIZE/NUMTHREADS)
shared [ FRACSIZE ] int table[SIZE];
shared [ 1 ] int *area_ptr[NUMTHREADS];
Предполагая, что вы используете среду компиляции static-threads, более краткий способ объявить ваш массив будет выглядеть примерно так:
#define SIZE 10000
shared [*] int table [ SIZE ]; /* data automatically blocked across THREADS */
shared [1] int *base = (shared [1] int *)&table;
Затем вы можете использовать циклический базовый указатель для создания указателя на общий ресурс, который ссылается на данные со сродством к потоку X с помощью выражения:
shared [] int *threadXdata = (shared [] int *)(base+X);
При таком подходе вам никогда не нужно создавать экземпляр хранилища для массива указателей THREADS. Однако, если вы действительно этого хотите, вы можете объявить и инициализировать что-то вроде этого:
shared [] int *threadptr[THREADS];
for (int i=0; i < THREADS; i++) threadptr[i] = (shared [] int *)(base+i);
...
threadptr[4][10] = 42; /* example access to element 10 on thread 4*/
Здесь threadptr - это локальный массив указателей, служащий каталогом ссылок на данные каждого потока.
Обратите внимание, что все вышеперечисленное использует неограниченно блокируемый указатель на общий для доступа к элементам со сродством к одному потоку, поскольку каждый блок логически представляет собой один непрерывный кусок данных без переноса между потоками.