来自CUDA我感兴趣的是如何从线程读取共享内存,并与CUDA的读取对齐要求进行比较。我将使用下面的代码作为示例:pthread从共享内存读取
#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中,读取需要进行合并 - pthread中是否存在类似的对齐限制?即如果我有两个线程从相同的共享地址读取,我假设某个调度程序必须将一个线程放在另一个线程之前。在CUDA中,这可能是一个代价高昂的操作,应该避免。是否存在对共享内存“同时”读取的惩罚 - 如果是这样的话,它是如此之小以至于可以忽略不计?即两个线程可能需要同时读取d-> datPtr [0] - 我假设内存读取不能同时发生 - 这种假设是否错误?
另外我读了article from intel,它说多线程时使用数组结构 - 这与cuda一致。如果我这样做,这几乎是不可避免的,我将需要线程ID - 我相信这将需要我使用互斥锁锁定线程ID直到它被读入线程的范围,这是真的还是会有其他方式识别线程?
关于多线程程序的内存管理的文章也将受到赞赏。
,但dataPtr在d中指向的数据是共享地址。在我的示例中,两个线程都从共享内存地址中读取数据以计算总和,并可能同时读取。我对这种情况的发生感兴趣 - 两个线程可以同时读取,还是有一些调度程序实际上将两个读取分开?如果两个线程*可以同时读取,这是如何工作的? – Marm0t 2011-06-07 19:09:42
这取决于。首先,读取序列将是非确定性的,这意味着除非添加同步机制,否则您将无法确定性地确定哪个线程将首先读取。这就是说,线程本地指针“d”不*指向共享内存。指针'd-> dataPtr' * *指向共享内存。在单处理器系统上,通过软件调度程序对'd-> dataPtr'进行仲裁。但是,在多处理器系统上,仲裁将在硬件内存控制器级完成。 – Jason 2011-06-07 19:43:22
之所以这样,是因为在单处理器系统上,基本上是在线程之间对处理器执行时间进行时间分割,软件调度程序处理在任何给定时间运行的线程。多处理器系统虽然可以同时执行两个不同的线程,但是如果两个处理器都试图读取完全相同的内存位置,那么仲裁不能在软件级完成,而是发生在硬件级别通过预取数据到本地缓存,发出缓存一致性调用等。 – Jason 2011-06-07 19:48:05