检测 OpenMP 竞争

检测 OpenMP 竞争

本教程演示如何使用 Coderect 检测使用 OpenMP 编写的单个文件多线程 C 程序中的种族。

先决条件
本教程假定您已经成功地安装了代码处理软件后,快速启动。
我们的示例代码依赖于OpenMP来实现并行性。您将需要一个支持 OpenMP 的编译器。我们将使用gcc,但clang和其他现代替代品也有 OpenMP 支持。
在 pi 中检测比赛.c
我们将从检测一个小的文件程序中的种族开始。该程序旨在计算 pi=3.1415926. …我们在 Coderrect 安装下的示例目录中提供此示例程序,或者您可以将下面的代码复制到您的系统。pi.c

//pi.c
#include <omp.h>
#include <stdio.h>

#define N 1000000000

int main () {

    double delta = 1.0/(double) N;
    int MAX_THREADS = omp_get_max_threads();
    // Compute parallel compute times for 1-MAX_THREADS
    for (int j=1; j<= MAX_THREADS; j++) {

        printf(" running on %d threads: ", j);
        omp_set_num_threads(j);

        double sum = 0.0;
        double start = omp_get_wtime();

        #pragma omp parallel for //reduction(+:sum)
        for (int i=0; i < N; i++) {
            double x = (i+0.5)*delta;
            sum += 4.0 / (1.0+x*x);
        }

        // Out of the parallel region, finalize computation
        double pi = delta * sum;
        double time_lapse = omp_get_wtime() - start;
        printf("PI = %.12g computed in %.4g seconds\n", pi, time_lapse);
    }
}

检查可编译并运行以下命令pi.c

gcc -fopenmp pi.c -o pi
./pi
您应该会看到如下所示的输出:

running on 1 threads: PI = 3.141592653589971 computed in 12.84 seconds
running on 2 threads: PI = 3.141593993623682 computed in 6.928 seconds
running on 3 threads: PI = 3.141594228301372 computed in 7.741 seconds
running on 4 threads: PI = 3.141595112697573 computed in 8.376 seconds
从结果中可以看到,在不同数量的线程上运行生成不同的 PI 值,指示并发错误的存在。

运行编码
运行该工具的最简单方法是将生成命令传递到 :coderrect

coderrect -t gcc -fopenmp pi.c
请记住,生成 pi 的命令.c。gcc -fopenmp pi.c

-t 开关用于在终端中生成快速摘要报告。

这样调用可确保在命令行上传递所有必需的编译标志。对于使用生成系统(如make)的项目,可以使用用于生成项目的相同生成命令调用工具。例如:签出基于Makefile 的项目中检测比赛。coderrectcoderrect

解释结果
该工具直接在终端中报告最有趣的比赛的快速摘要,以便快速查看。该工具还生成更全面的报告,可以在浏览器中查看。coderrect

终端报告
pi 的终端.c应如下所示:

==== Found a race between: 
line 22, column 13 in test.c AND line 22, column 17 in test.c
Shared variable:
 at line 16 of test.c
 16|        double sum = 0.0;
Thread 1:
 20|        for (int i=0; i < N; i++) {
 21|            double x = (i+0.5)*delta;
>22|            sum += 4.0 / (1.0+x*x);
 23|        }
 24|
>>>Stacktrace:
Thread 2:
 20|        for (int i=0; i < N; i++) {
 21|            double x = (i+0.5)*delta;
>22|            sum += 4.0 / (1.0+x*x);
 23|        }
 24|
>>>Stacktrace:
             1 OpenMP races

每个报告的比赛从找到比赛的总结开始。

==== Found a race between:
line 22, column 13 in test.c AND line 22, column 17 in test.c
接下来,报表显示发生比赛的变量名称和位置。

Shared variable:
at line 16 of test.c
16| double sum = 0.0;
这表明比赛发生在第 16 行声明的变量上。sum

在代码中查找比赛位置可能有点乏味,因此报表还显示该位置的文件预览。

Thread 1:
20| for (int i=0; i < N; i++) {
21| double x = (i+0.5)*delta;

22| sum += 4.0 / (1.0+x*x);
23| }
代码片段显示,此赛车访问是作为 OpenMP 并行 for 循环的一部分写入的。sum

仔细看看源代码,我们可以看到根本原因是评论出"减少"。

#pragma omp parallel for //reduction(+:sum)
取消注释将删除数据竞赛,并允许程序正确计算 pi。reduction(+:sum)sum

HTML 报告
终端是伟大的,可以快速了解什么比赛报告,但完整的报告可以在浏览器中查看。

我们还可以将比赛报告保存到通过命令选项指定的目录。-o

coderrect -o report gcc -fopenmp pi.c
这创建了一个名为目录和该目录中命名的文件。若要查看完整报告,请打开浏览器中的文件。reportindex.htmlindex.html

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值