gpt4 book ai didi

c - 使用 OpenMP 按列和按行并行矩阵乘以 vector

转载 作者:太空宇宙 更新时间:2023-11-04 05:58:09 24 4
gpt4 key购买 nike

对于我的一些作业,我需要实现矩阵与 vector 的乘法,并按行和按列并行化。我确实理解行版本,但我对列版本有点困惑。

假设我们有以下数据:

Matix times vector

以及行版本的代码:

#pragma omp parallel default(none) shared(i,v2,v1,matrix,tam) private(j)
{
#pragma omp for
for (i = 0; i < tam; i++)
for (j = 0; j < tam; j++){
// printf("Hebra %d hizo %d,%d\n", omp_get_thread_num(), i, j);
v2[i] += matrix[i][j] * v1[j];
}
}

这里计算正确,结果正确。

专栏版本:

#pragma omp parallel default(none) shared(j,v2,v1,matrix,tam) private(i)
{
for (i = 0; i < tam; i++)
#pragma omp for
for (j = 0; j < tam; j++) {
// printf("Hebra %d hizo %d,%d\n", omp_get_thread_num(), i, j);
v2[i] += matrix[i][j] * v1[j];
}
}

这里,由于并行化的完成方式,每次执行的结果都会有所不同,具体取决于执行每一列的线程。但它发生了一些有趣的事情,(我认为是因为编译器优化)如果我取消注释 printf 那么结果与行版本完全相同,因此是正确的,例如:

Thread 0 did 0,0
Thread 2 did 0,2
Thread 1 did 0,1
Thread 2 did 1,2
Thread 1 did 1,1
Thread 0 did 1,0
Thread 2 did 2,2
Thread 1 did 2,1
Thread 0 did 2,0

2.000000 3.000000 4.000000
3.000000 4.000000 5.000000
4.000000 5.000000 6.000000


V2:
20.000000, 26.000000, 32.000000,

是对的,但是如果我删除 printf:

V2:
18.000000, 11.000000, 28.000000,

我应该使用什么样的机制来获得正确的列版本?

注意:我更关心的是解释,而不是您可能作为答案发布的代码,因为我真正想要的是了解专栏版本中出了什么问题。

编辑

我找到了一种摆脱 Z 玻色子在他的回答中提出的私有(private) vector 的方法。我用一个变量替换了那个 vector ,这里是代码:

    #pragma omp parallel
{
double sLocal = 0;
int i, j;
for (i = 0; i < tam; i++) {
#pragma omp for
for (j = 0; j < tam; j++) {
sLocal += matrix[i][j] * v1[j];
}
#pragma omp critical
{
v2[i] += sLocal;
sLocal = 0;
}
}
}

最佳答案

我不确切知道您的家庭作业沿行和列并行化意味着什么,但我知道为什么您的代码无法正常工作。当您写入 v2[i] 时,您会遇到竞争条件。您可以通过制作私有(private)版本的 v2[i]、并行填充它们,然后将它们与关键部分合并来修复它。

#pragma omp parallel
{
float v2_private[tam] = {};
int i,j;
for (i = 0; i < tam; i++) {
#pragma omp for
for (j = 0; j < tam; j++) {
v2_private[i] += matrix[i][j] * v1[j];
}
}
#pragma omp critical
{
for(i=0; i<tam; i++) v2[i] += v2_private[i];
}
}

我测试过这个。你可以在这里看到结果 http://coliru.stacked-crooked.com/a/5ad4153f9579304d

请注意,我没有明确定义任何共享或私有(private)的内容。没必要做。有些人认为您应该明确定义一切。我个人认为相反。通过在并行部分中定义 ij(以及 v2_private),它们被设为私有(private)。

关于c - 使用 OpenMP 按列和按行并行矩阵乘以 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23277508/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com