我有使用openmp的矩阵乘法代码:
#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main()
{
long int i, j, k;
//long int N = atoi(argv[1]);
double t1, t2;
double a[N][N],b[N][N],c[N][N];
for (i=0; i<N; i++)
for (j=0; j<N; j++)
a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
t1=omp_get_wtime();
#pragma omp parallel for shared(a, b, c) private(i, j, k)
for(i=0; i<N; i++){
for(j=0; j<N; j++){
c[i][j] = 0.0;
for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
}
}
t2=omp_get_wtime();
printf("Time=%lf\n", t2-t1);
}
现在我想通过命令行设置我想要的线程数。我是通过使用
来做到的atoi(argv[])
即
#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N 1000
int main(int argc, char** argv[])
{
long int i, j, k;
//long int N = atoi(argv[1]);
double t1, t2;
double a[N][N],b[N][N],c[N][N];
for (i=0; i<N; i++)
for (j=0; j<N; j++)
a[i][j]=b[i][j]=log(i*j/(i*j+1.)+1) +exp(-(i+j)*(i+j+1.));
int t = atoi(argv[1]);
t1=omp_get_wtime();
#pragma omp parallel for shared(a, b, c) private(i, j, k) num_threads(t)
for(i=0; i<N; i++){
for(j=0; j<N; j++){
c[i][j] = 0.0;
for(k=0; k<N; k++) c[i][j]+=a[i][k]*b[k][j];
}
}
t2=omp_get_wtime();
printf("Time=%lf\n", t2-t1);
}
一切都很好,除了一件至关重要的事情:当我尝试计算尺寸大于(或多或少)500的矩阵的乘积时,我得到了错误:&#34;分段错误&#34;。有人可以澄清这个错误的原因吗?
答案 0 :(得分:1)
我对openmp
一无所知,但你肯定会炸毁你的筹码。默认堆栈空间因系统而异,但对于N == 1000
,您试图在堆栈上放置三个总共300万double
的2D阵列。假设double
是8个字节,那是2400万字节,或者只是22.9MB。不能有许多系统允许这种堆栈空间。相反,我建议尝试从堆中获取大量内存。像这样:
//double a[N][N],b[N][N],c[N][N];
double **a, **b, **c;
a = malloc(sizeof(double*) * N);
b = malloc(sizeof(double*) * N);
c = malloc(sizeof(double*) * N);
for (i=0; i<N; i++)
{
a[i] = malloc(sizeof(double) * N);
b[i] = malloc(sizeof(double) * N);
c[i] = malloc(sizeof(double) * N);
}
// do your calculations
for (i=0; i<N; i++)
{
free(a[i]);
free(b[i]);
free(c[i]);
}
free(a);
free(b);
free(c);
我至少在我的计算机上验证过,N == 1000
尝试将这些数组放在堆栈上时,EXC_BAD_ACCESS
使用select *
from sys.databases
where name = '<your_db>'
and source_database_id is not null
崩溃了。当我如上所示动态分配内存时,我没有遇到seg错误。