Исходя из CUDA, меня интересует, как разделяемая память читается из потока и сравнивается с требованиями выравнивания чтения CUDA. В качестве примера я буду использовать следующий код:
#include <sys/unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define THREADS 2
void * threadFun(void * args);
typedef struct {
float * dataPtr;
int tIdx,
dSize;
} t_data;
int main(int argc, char * argv[])
{
int i,
sizeData=5;
void * status;
float *data;
t_data * d;
pthread_t * threads;
pthread_attr_t attr;
data=(float *) malloc(sizeof(float) * sizeData );
threads=(pthread_t *)malloc(sizeof(pthread_t)*THREADS);
d = (t_data *) malloc (sizeof(t_data)*THREADS);
data[0]=0.0;
data[1]=0.1;
data[2]=0.2;
data[3]=0.3;
data[4]=0.4;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i=0; i<THREADS;i++)
{
d[i].tIdx=i;
d[i].dataPtr=data;
d[i].dSize=sizeData;
pthread_create(&threads[i],NULL,threadFun,(void *)(d+i));
}
for (i=0; i<THREADS; i++)
{
pthread_join(threads[i],&status);
if(status);
//Error;
}
return 0;
}
void * threadFun(void * args)
{
int i;
t_data * d= (t_data *) args;
float sumVal=0.0;
for (i=0; i<d->dSize; i++)
sumVal+=d->dataPtr[i]*(d->tIdx+1);
printf("Thread %d calculated the value as %-11.11f\n",d->tIdx,sumVal);
return(NULL);
}
В threadFun весь указатель d указывает на пространство общей памяти (я полагаю). Из того, что я встречал в документации, чтение из нескольких потоков нормально. В CUDA чтения должны быть объединены - есть ли аналогичные ограничения выравнивания в pthreads? т.е. если у меня есть два потока, читающих с одного и того же общего адреса, я предполагаю, что где-то на линии планировщик должен поместить один поток впереди другого. В CUDA это может быть дорогостоящей операцией, и ее следует избегать. Есть ли штраф за «одновременное» чтение из общей памяти — и если да, то настолько ли он мал, что им можно пренебречь? то есть обоим потокам может потребоваться одновременное чтение d->datPtr[0] - я предполагаю, что чтение памяти не может происходить одновременно - это предположение неверно?
Также я прочитал статью от Intel в котором говорится, что при многопоточности используется структура массивов - это согласуется с cuda. Однако, если я это сделаю, мне почти неизбежно понадобится идентификатор потока, который, как я полагаю, потребует от меня использования блокировки мьютекса идентификатора потока до тех пор, пока он не будет прочитан в области потока, это правда или есть какой-то другой способ идентифицировать темы?
Также хотелось бы получить статью об управлении памятью для многопоточных программ.