【请教+讨论】C/C++ 大量随机数生成性能问题

ambitionzfx 2012-05-28 04:40:12
各路大神们,c/c++ 自带的srand();rand()函数使用起来比较方便,但是感觉性能不太好,比较耗时,
背景: 针对图像的每一个像素(640*480),会做30-50次的随机数生成,需要保证每次生成的随机数不同,因此每一次都需要srand()一下,再rand()一下,通过VS性能测试工具发现我的测试程序大部分时间都花在这两个函数下。

请教:
有没有性能更好的随机数生成方法? 或者说在这个背景下,如何提高随机数生成函数的效率?
...全文
892 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-05-29
  • 打赏
  • 举报
回复
//随机产生N=640*480*30个取值范围为M=1~640*480*30*2的不重复的随机数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <malloc.h>
#define N 640*480*30
#define M 640*480*30*2
int i,a,b;
unsigned long ul,t;
unsigned long *d;
unsigned long ulrand(void) {
return (
(((unsigned long)rand()<<24)&0xFF000000ul)
|(((unsigned long)rand()<<12)&0x00FFF000ul)
|(((unsigned long)rand() )&0x00000FFFul));
}
void main() {
d=(unsigned long *)malloc(M*sizeof(unsigned long));
if (NULL==d) {
printf("Can not malloc(%d)!\n",M*sizeof(unsigned long));
return;
}
for (i=0;i<M;i++) d[i]=(unsigned long)i+1;
srand(time(NULL));
for (i=M;i>0;i--) {/* 打乱d[0~M-1] */
a=i-1;b=ulrand()%i;
if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
}
for (i=0;i<N;i++) printf("%08lu\n",d[i]);
free(d);
}

运行时将结果重定向到文件中比如在cmd窗口中
shuffle.exe >out.txt
用时不到10秒!
ambitionzfx 2012-05-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
srand只是初始随机发送器的,没有必要每次都进行调用。只需要调用一次srand,多次调用rand可以获得随机数
[/Quote]
说的是~~~现在遇到的问题是因为在一次主循环中要做 640*480*30 多次随机数生成。。所以想提高其运行速度
jackyjkchen 2012-05-29
  • 打赏
  • 举报
回复
CryptoAPI和10楼给的linux的随机数设备

很多跨平台库都是用预处理将这两种随机数产生方法封装的
qq120848369 2012-05-29
  • 打赏
  • 举报
回复
[User:root Time:13:06:07 Path:/home/liangdong/c]$ ./output 
211224302
48391966
1725535402
1446122221
2755167891
3295194106
3197570105
2983542393
615933470
1795109028
91720513
764037545
1583518780
3656489667
122144737
4130644217
2554011625
397826093
1025195296
567415520
3744238597
2057238149
3879090146
3917676704
677506327
2702769844
2963660401
493729977
1072139505
3004186491
1129189395
2133119042
671665964
3759724610
3963613494
277643425
2495263398
2245264738
1150582893
3945362546
234371862
339748457
175301269
3556113117
3339768640
3053510114
2764929346
135153055
479459479
3279498197
[User:root Time:13:06:08 Path:/home/liangdong/c]$ ./output
731919894
1147893534
1563917266
2445224879
2662737291
1894737694
3969870244
2688020049
3248632517
2896822153
2304617576
1805955706
1750586186
409043451
1835070164
1398019960
1583018616
4101595095
4132395958
3110547409
3321535743
1040527731
2312987348
1298861080
3600127718
1743446828
2500345809
1032981170
1990478561
1638341937
2253996195
4080424278
3106835316
3056152539
3325069072
2953884061
2707054833
2078151107
2873434137
1505192202
829304226
1415009444
3646716850
455697366
176479699
314121003
3516828737
3380813547
1967741333
1479422566
[User:root Time:13:06:08 Path:/home/liangdong/c]$ cat src/main.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char* const argv[]) {
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
return 1;
}
unsigned int n, i;
for (i = 0; i != 50; ++ i) {
int ret = read(fd, &n, sizeof(n));
if (ret != sizeof(n)) {
return 2;
}
printf("%u\n", n);
}
return 0;
}
W170532934 2012-05-28
  • 打赏
  • 举报
回复
srand只是初始随机发送器的,没有必要每次都进行调用。只需要调用一次srand,多次调用rand可以获得随机数
飞天御剑流 2012-05-28
  • 打赏
  • 举报
回复
可参考如下方法:http://blog.csdn.net/supermegaboy/article/details/4875601

ambitionzfx 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
随机必然有重复,所谓“不重复的随机”根本不是随机,而是洗牌。洗牌算法参考下面

C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int d[6];
int i,n,a,b,t;
int c,j;
void main() {
srand(time(NULL));
printf……
[/Quote]
谢谢ls,其实我想生成的就是伪随机数,上面说得太严格了。。可以有重复的
赵4老师 2012-05-28
  • 打赏
  • 举报
回复
srand只需且只能在程序初始化时调用一次。
赵4老师 2012-05-28
  • 打赏
  • 举报
回复
随机必然有重复,所谓“不重复的随机”根本不是随机,而是洗牌。洗牌算法参考下面
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int d[6];
int i,n,a,b,t;
int c,j;
void main() {
srand(time(NULL));
printf("shuffle 0..n-1 demo\n");
for (n=1;n<=5;n++) {/* 测试1~5个元素 */
printf("_____n=%d_____\n",n);
j=1;
for (c=1;c<=n;c++) j=j*c;/* j为n! */
j*=n*2;
for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
for (i=0;i<n;i++) d[i]=i;/* 填写0~n-1 */
for (i=n;i>0;i--) {/* 打乱0~n-1 */
a=i-1;b=rand()%i;
if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
}
printf("%04d:",c);
for (i=0;i<n;i++) printf("%d",d[i]);
printf("\n");
}
}
printf("shuffle 1..n demo\n");
for (n=1;n<=5;n++) {/* 测试1~5个元素 */
printf("_____n=%d_____\n",n);
j=1;
for (c=1;c<=n;c++) j=j*c;/* j为n! */
j*=n*2;
for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
for (i=1;i<=n;i++) d[i]=i;/* 填写1~n */
for (i=n;i>1;i--) {/* 打乱1~n */
a=i;b=rand()%i+1;
if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
}
printf("%04d:",c);
for (i=1;i<=n;i++) printf("%d",d[i]);
printf("\n");
}
}
}
ambitionzfx 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
动态访问未知内存截取数据,可以尝试==感觉像是搞破坏的!~
[/Quote]
ls做过实验不,怕不靠谱哦~~
酱油党 2012-05-28
  • 打赏
  • 举报
回复
动态访问未知内存截取数据,可以尝试==感觉像是搞破坏的!~

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧