各位兄弟 帮忙看一下 如下代码能改成并行执行吗?多谢
主要是循环有依赖
//函数 是获取200个没有重复的数字0-199
int __stdcall GET200 (int iNumber,int *iAddr)
{
for (int j=0; j<200; j++) iAddr[j] = -1;;
srand(iNumber); //随机种子
int Num;
byte bExist;
for (int i=0; i<200; i++)
{
bExist = 0;
while (1)
{
Num = (rand())%200;
for (int j=0; j<i;j++) //主要是这边
{
if (iAddr[j]==Num)
{
bExist = 1;
break;
}
}
if (bExist==0)
{
iAddr[i] = Num;
break;
}
else
bExist = 0;
}
}
return 0;
}
//剩下的我用类C 语言描述(估计也有可能设计到 转换
struct sNUM
{
int iNumber;
int bbuf [0…200] ;
}
int main()
{
sNum* num=(sNUM*)malloc(5000000*sizeof(sNUM));//申请500w 条记录
int btmp [0…200] ;
for(int j=0;j<5000000;j++)
{
GET200(j,btmp); //生成一条记录
num[j].iNumber=j;
copymemory(num[j].bbuf,btmp,sizeof(btmp)); //存入
}
saveToFile(num);//保存到文件
}
[/i]
LZ您好,大致看了一下您的代码。
按照您生成随机性顺序的0~199整数的代码,似乎不能直接改写为并行的,因为您每一步生成的结果都需要和之前所有的结果比对,这是一个后一步依赖于前一步结果的串行方法 。
不过,如果将0~199按照从小到大分为多个组,比如说10组,每组负责寻找自己区间里面的数字,这样生成就没问题了,但是顺序不是随机的,还需要处理。
实际上,您200个数字其实是确定的,只是顺序不同,所以数字实际上不需要您生成,您只需要将顺序的0~199采用随机的方式打乱次序即可。不知这样能否提高您的效率。比如生成整数随机数——对应位置的值写到所需列表里面——对应位置置-1——再生成如果检测到对应位置是-1则表示重复,不为-1则对应位置的值拿到所需列表里面。这样不用每次都反复循环比较。
以及,您可能还需要考虑curand如何使用效率较高,是一次性生成多个随机数呢,还是每次调用。
此外,您每次生成200个随机顺序的序列计算量虽然不大,但是您后面总共需要生成的却很多,您可以考虑一次生成很多组,以跑满您的GPU。
以上是一点初步看法,供您参考,抛砖引玉,望大家补充~
祝您编码愉快~
嗯 多谢 ice 老兄 指导,“实际上,您200个数字其实是确定的,只是顺序不同,”
仔细研究一下 确实是这样的。 我再把源代码 研究一下,看 能不能变通一下。
CUDA 可以并行化我感觉就是满足两个条件
1:整个程序由多个步骤,每一个步骤可以并行完成
2:即使每一个步骤不能并行,如果每一个原子操作可以并行也可以
通过测试,ice老兄说的没错。可以分成2步走。
1.while 循环里面 最多不会超过4096,所以可以定义一个长数组 直接生成4096个数
for (int i:=0;i<4096;i++)
{
iAddr[i]= rand()%200;
}
2.然后从4096中把重复的筛选出来
for(int i:=0;i<4096;i++)
{
//从第一个开始去掉重复的 一直到200
}
请问这样话可以改成并行的吗?
我觉得按照你这样的方法,有两个问题
1:您的第二步自身依然是后面依赖前面的结果,所以生成200个一组这个过程是无法并行的,但是可以同时跑多组。
2:您准备了4096个随机数,但这并无100%把握保证一定能从此生成200个不同的数字,也许在非常小概率的情况下这里面没有200个不同的数字,因此会出问题。