- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在我的大学里做一个事件,需要填充 [2000][2000] 个元素的矩阵,然后以并行方式计算所有元素的总和,这些元素是 5 的倍数。
起初我尝试使用 5 x 5 矩阵,我对元素进行了部分求和 (sumP),然后将它们的所有元素添加到一个名为 Sum 的变量上到一个临界区域。
在我的大学计算机上,当值必须低于 100 时,部分和正在接收 thrash 值(如 36501);我注意到它只发生在矩阵的 [0][i](第 0 行)。
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#define N 5
int main() {
int i, j, k, l;
int sum = 0;
int sumP = 0;
int A[N][N];
printf("sumP : %i\n", sumP );
printf("sum: %i\n", sum);
#pragma omp parallel shared (A) private (i, j)
{
#pragma omp for
for (i = 0; i < N; i++) {
for(j = 0; j < N; j++){
A[i][j] = i%5;
printf("Number: %i, pos[%i][%i]\n", A[i][j], i, j);
}
}
}
#pragma omp parallel shared(A, sum) private (k, l, sumP)
{
#pragma omp for
for (k = 0; k < N; k++) {
for (l = 0; l < N; l++){
if (A[l][k] % 5 == 0 && A[l][k] != 0){
sumP = sumP + A[k][l];
printf("numero: %i, pos [%i],[%i] sumP: %i\n", A[k][l], k, l, sumP);
}
}
}
#pragma omp critical
sum += sumP;
}
//printf("sumP: %i\n", sumP);
printf("sum: %i\n", sum);
return (0);
}
我测试了它,在“for”语句之间将 sumP 的值声明为 0,它起作用了:
#pragma omp parallel shared(A, soma) private (k, l, somap2)
{
#pragma omp for
for (k = 0; k < N; k++) {
sumP = 0;
for (l = 0; l < N; l++){
当我在家对其进行测试时,它无需将 sumP 声明为 0(在部分和“sumP”上)就可以工作,就像我在上面所做的那样,但现在最终的 Sum 结果不正确...
最佳答案
您观察到此行为是因为 OpenMP 中的 private
变量未初始化。准确地说,它们的初始化就像您拥有一个没有显式初始化的局部变量一样。这意味着它们最初的值(value)是不确定的。您会在不同的系统上观察到不同的行为,因为编译器、选项和操作系统的某些组合以不同方式使用此“未定义”。您的代码在任何情况下都是不正确的,即使它有时会产生正确的结果。
现在您可以在尝试时将此设置设为零。但是,我通常建议改为尽可能将变量声明为局部变量。这使得对(并行)代码的推理变得更加容易,并且您可以省略“私有(private)/共享”声明。所以你的代码看起来像这样:
#pragma omp parallel
{
int sumP = 0;
#pragma omp for
for (int k = 0; k < N; k++) {
for (int l = 0; l < N; l++) {
if (A[l][k] % 5 == 0 && A[l][k] != 0) {
sumP = sumP + A[k][l];
printf("numero: %i, pos [%i],[%i] sumP: %i\n", A[k][l], k, l, sumP);
}
}
}
#pragma omp critical
sum += sumP;
}
除此之外,还有另一种方法可以通过归约来大幅简化此代码:
#pragma omp parallel for reduction(+:sum)
for (int k = 0; k < N; k++) {
for (int l = 0; l < N; l++) {
if (A[l][k] % 5 == 0 && A[l][k] != 0) {
sum += A[k][l];
}
}
}
编译器基本上会为你做同样的事情(但更好)并且代码更清晰。
关于c - 平行区域上的矩阵元素之和导致 OpenMP 上的错误答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57984116/
这个问题在这里已经有了答案: Can I get `cabal install` to use multiple cores? (3 个回答) 关闭 7 年前。 在使用类似于 GNU make 的 -
我正在尝试通过 akeeba backup 在 parallels plesk 面板中安装一个 joomla 站点。我在哪里面临文件权限问题。 An error occured Could not o
我在 MATLAB 中使用箱线图函数。我需要为 6 个“XTicks”绘制 6 个不同数据集的箱线图,即 x 轴上的每个刻度线应包含 6 个相应的框、晶须、中线和其域内的异常值集。我尝试通过为每个变量
我需要在 Kaplan Meier 图上呈现 at_risk 数字。 最终结果应该与此类似: 我在渲染时遇到的问题是 No。处于危险中的患者数量位于图表底部。此处显示的值对应于 x 轴上的值。因此本质
我想知道你们中的任何一个人为什么知道我的表现糟透了吗? 我正在努力实现的目标; 生成220万个文件。要创建每个文件,平均需要2-5个数据库调用。 我正在使用的服务器具有24个内核和190GB的RAM。
请帮忙。我正在研究具有此要求的算法。 给定 4 个“右”矩形(右矩形的边平行于 x 或 y),找出它们中的任何一个覆盖的区域 例如,灰色区域被下图中的 4 个矩形中的任何一个覆盖。 enter ima
我是一名优秀的程序员,十分优秀!