來自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