我正在尝试将我的C项目从顺序编程转换为并行编程.尽管为此目的,大多数代码现在已经从头开始重新设计,但随机数的生成仍然是其核心.因此,随机数发生器(RNG)的不良性能会严重影响程序的整体性能.
我写了一些代码行(见下文),以显示我面临的问题而没有太多冗长.
问题如下:每次线程数增加时,性能都会明显变差.在这个工作站(linux内核2.6.33.4; gcc 4.4.4; intel四核CPU)中,无论迭代次数n多少,并行for循环使用nt = 4比使用nt = 1大约长10倍.
这种情况似乎在这里有所描述,但焦点主要集中在fortran,这是一种我对此知之甚少的语言,所以我非常感谢一些帮助.
我试图按照他们的想法创建不同的RNG(使用不同的种子)来访问每个线程,但性能仍然很差.实际上,每个线程的这个不同的播种点也让我感到困惑,因为我无法看到最终如何保证生成的数字的质量(缺乏相关性等).
我已经考虑过完全放弃GSL并自己实现一个随机生成器算法(例如Mersenne-Twister),但我怀疑我稍后会遇到同样的问题.
非常感谢您提供的答案和建议.请问我可能忘记提及的任何重要事项.
编辑:由lucas1024(pragma for-loop声明)和JonathanDursi(播种;将"a"设置为私有变量)建议的更正.多线程模式下的性能仍然非常低迷.
编辑2:实施Jonathan Dursi建议的解决方案(见评论).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gsl/gsl_rng.h>
#include <omp.h>
double d_t (struct timespec t1, struct timespec t2){
return (t2.tv_sec-t1.tv_sec)+(double)(t2.tv_nsec-t1.tv_nsec)/1000000000.0;
}
int main (int argc, char *argv[]){
double a, b;
int i,j,k;
int n=atoi(argv[1]), seed=atoi(argv[2]), nt=atoi(argv[3]);
printf("\nn\t= %d", n);
printf("\nseed\t= %d", seed);
printf("\nnt\t= %d", nt);
struct timespec t1, t2, t3, t4;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
//initialize gsl random …Run Code Online (Sandbox Code Playgroud) 我一直致力于数据集并使用glmnet进行线性LASSO/Ridge回归.
为简单起见,我们假设我使用的模型如下:
cv.glmnet(train.features, train.response, alpha=1, nlambda=100, type.measure = "mse", nfolds = 10)
Run Code Online (Sandbox Code Playgroud)
我正在为客户准备一个演示文稿,我需要显示变量的T-stat和R平方值.另外,我还需要根据模型的拟合值绘制残差.
在创建从头开始执行此操作的功能之前,我想询问库中是否已涵盖此功能.我检查了glmnet插图,但没有找到任何东西.
谢谢你的帮助!
我想使用filled.contour()来绘制矩阵中的一些数据.
一切都很完美,直到我将图形导入我的tex文件并意识到我需要使用字体大小才能在最终文档中读取它.
不幸的是,似乎我无法调filled.contour(参数CEX),同样也适用于拉斯维加斯(我想了ylabel平行于X轴).
下面是一个简单的例子.虽然我希望输出在每种情况下都不同,即字体大小,但生成的图表几乎是相同的.
非常感谢你能给我的任何帮助.
x=1:10
y=1:10
z=array(rnorm(100),dim=c(10,10))
filled.contour(x,y,z)
filled.contour(x,y,z,xlab='x',ylab='y')
filled.contour(x,y,z,xlab='x',ylab='y',las=1)
filled.contour(x,y,z,xlab='x',ylab='y',las=1,cex=2)
filled.contour(x,y,z,xlab='x',ylab='y',las=1,cex=20)
Run Code Online (Sandbox Code Playgroud) 我的动机:我使用算法来模拟种群动态,我希望使用CUDA,以便能够在数值模拟中考虑大量节点.虽然这是我第一次在GPU上运行代码,但到目前为止结果看起来很有希望.
背景:我需要考虑随机噪声,它在我要研究的复杂系统的演化中起着至关重要的作用.据我所知,与CPU上的类似操作相比,CUDA中的随机数生成可能非常麻烦.在文档中,我看到必须存储RNG的状态并继续将其提供给需要(生成和)使用随机数的内核(全局函数).我发现这些例子很有启发性,也许还有其他一些你建议我阅读的内容?
问题:生成n个种子值的优点是什么,将它们存储在设备全局内存中的数组中,然后将它们提供给内核,后者又生成几个随机数,而不是生成2n个随机数,存储它们在设备全局内存中,然后直接将它们提供给需要使用它们的内核?我必须在这里遗漏一些真正重要的东西,因为它肯定会让我觉得在第二种情况下可以节省资源(在示例中从未使用过).似乎人们对生成的数字的分布更安全.
我的代码很长,但我试着做一个我需要的简短例子.这里是:
我的代码:
#include <cstdlib>
#include <stdio.h>
#include <cuda.h>
#include <curand.h>
#include <math.h>
__global__ void update (int n, float *A, float *B, float p, float q, float *rand){
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int n_max=n*n;
int i, j;
i=idx/n; //col
j=idx-i*n; //row
float status;
//A, B symmetric
//diagonal untouched, only need 2 random numbers per thread
//i.e. n*(n-1) random numbers in total
int idx_rand = (2*n-1-i)*i/2+j-1-i;
if(idx<n_max && j>i){
if(rand[idx_rand]<p){
status=A[idx];
if(status==1){ …Run Code Online (Sandbox Code Playgroud)