向量OpenMP-C的矩阵乘法
我正在尝试用C(OpenMP)编写向量乘法矩阵 但当我添加处理器时,我的程序会变慢向量OpenMP-C的矩阵乘法,c,openmp,C,Openmp,我正在尝试用C(OpenMP)编写向量乘法矩阵 但当我添加处理器时,我的程序会变慢 1 proc - 1,3 s 2 proc - 2,6 s 4 proc - 5,47 s 我在我的电脑(CoreI5)和我们学校的集群上测试了这个,结果是一样的(程序变慢) 这是我的代码(矩阵是10000 x 10000),向量是10000: double start_time = clock(); #pragma omp parallel private(i) num_threads(4) { ti
1 proc - 1,3 s
2 proc - 2,6 s
4 proc - 5,47 s
我在我的电脑(CoreI5)和我们学校的集群上测试了这个,结果是一样的(程序变慢)
这是我的代码(矩阵是10000 x 10000),向量是10000:
double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
tid = omp_get_thread_num();
world_size = omp_get_num_threads();
printf("Threads: %d\n",world_size);
for(y = 0; y < matrix_size ; y++){
#pragma omp parallel for private(i) shared(results, vector, matrix)
for(i = 0; i < matrix_size; i++){
results[y] = results[y] + vector[i]*matrix[i][y];
}
}
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
对于(y=0;y
我的问题是:有什么错误吗?对我来说,这似乎很简单,应该会加快速度。我已经有一段时间没有做过任何并行编程了,也没有做过任何数学计算,但是你不想并行分割矩阵的行,而不是列吗 如果您尝试以下操作,会发生什么情况:
double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
tid = omp_get_thread_num();
world_size = omp_get_num_threads();
printf("Threads: %d\n",world_size);
#pragma omp parallel for private(y) shared(results, vector, matrix)
for(y = 0; y < matrix_size ; y++){
for(i = 0; i < matrix_size; i++){
results[y] = results[y] + vector[i]*matrix[i][y];
}
}
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
#pragma omp并行专用(y)共享(结果、向量、矩阵)
对于(y=0;y
另外,您确定使用
openMP
编译和链接一切正常吗?我已经有一段时间没有做过任何并行编程了,也没有做过任何数学计算,但是您不想并行分割矩阵的行,而不是列吗
如果您尝试以下操作,会发生什么情况:
double start_time = clock();
#pragma omp parallel private(i) num_threads(4)
{
tid = omp_get_thread_num();
world_size = omp_get_num_threads();
printf("Threads: %d\n",world_size);
#pragma omp parallel for private(y) shared(results, vector, matrix)
for(y = 0; y < matrix_size ; y++){
for(i = 0; i < matrix_size; i++){
results[y] = results[y] + vector[i]*matrix[i][y];
}
}
}
double end_time = clock();
double result_time = (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time: %f\n", result_time);
double start_time=clock();
#pragma omp并行专用(i)num_线程(4)
{
tid=omp_get_thread_num();
world_size=omp_get_num_threads();
printf(“线程:%d\n”,世界大小);
#pragma omp并行专用(y)共享(结果、向量、矩阵)
对于(y=0;y
另外,您确定使用
openMP编译和链接时一切正常吗?您有一个典型的缓存冲突案例
假设CPU上的缓存线可能有64字节长。让一个处理器/核心写入前4个字节(float
)会导致每隔一个一级/二级缓存线失效,也可能是三级缓存线失效。这是一大笔开销
更好地划分数据
#pragma omp parallel for private(i) shared(results, vector, matrix) schedule(static,16)
我们应该做到这一点。如果这没有帮助,请增加chunksize
另一种优化方法是在将结果刷新到内存之前将其本地存储
此外,这是一个OpenMP的东西,但您不需要为循环启动一个新的并行区域(每次提到parallel
都会启动一个新团队):
#pragma omp并行默认值(无)\
共享(向量、矩阵)\
firstprivate(矩阵大小)\
线程数(4)
{
int i,y;
#计划的pragma omp(静态,16)
对于(y=0;y
您有一个典型的缓存冲突案例
假设CPU上的缓存线可能有64字节长。让一个处理器/核心写入前4个字节(float
)会导致每隔一个一级/二级缓存线失效,也可能是三级缓存线失效。这是一大笔开销
更好地划分数据
#pragma omp parallel for private(i) shared(results, vector, matrix) schedule(static,16)
我们应该做到这一点。如果这没有帮助,请增加chunksize
另一种优化方法是在将结果刷新到内存之前将其本地存储
此外,这是一个OpenMP的东西,但您不需要为循环启动一个新的并行区域(每次提到parallel
都会启动一个新团队):
#pragma omp并行默认值(无)\
共享(向量、矩阵)\
firstprivate(矩阵大小)\
线程数(4)
{
int i,y;
#计划的pragma omp(静态,16)
对于(y=0;y
我基本上已经回答了这个问题
当您写入结果[y]
时,您有一个竞争条件。要解决这个问题,并且仍然并行化内部循环,您必须创建结果[y]
的私有版本,并行填充它们,然后将它们合并到关键部分
在下面的代码中,我假设您使用的是double
,将其替换为float
或int
或您正在使用的任何数据类型(请注意,您的内部循环遍历了矩阵[I][y]
的第一个索引,这是缓存不友好的)
#pragma omp并行num_线程(4)
{
int y,i;
double*results\u private=(double*)calloc(矩阵大小,sizeof(double));
对于(y=0;y 对于(y=0;y我基本上已经回答了这个问题
当您写入结果[y]
时,您有一个竞争条件。要解决这个问题,并且仍然并行内部循环,您必须创建的私有版本