使用omp技术实现wordcount算法

news2024/10/6 6:49:56

【问题描述】

编写程序统计一个英文文本文件中每个单词的出现次数(词频统计),并将统计结果按单词字典序输出到屏幕上。

注:在此单词为仅由字母组成的字符序列。包含大写字母的单词应将大写字母转换为小写字母后统计。

【输入形式】

打开当前目录下文件article.txt,从中读取英文单词进行词频统计。

【输出形式】

程序将单词统计结果按单词字典序输出到屏幕上,每行输出一个单词及其出现次数,单词和其出现次数间由一个空格分隔,出现次数后无空格,直接为回车。

【样例输入】

当前目录下文件article.txt内容如下:

Do not take to heart every thing you hear.;

Do not spend all that you have.;

Do not sleep as long as you want;

【样例输出】

all 1

as 2

do 3

every 1

have 1

hear 1

heart 1

long 1

not 3

sleep 1

spend 1

take 1

that 1

thing 1

to 1

want 1

you 3

【样例说明】

输出单词及其出现次数。
数据集下载:wordcount数据集

提取码:k3v2

代码实现:

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <omp.h>
using namespace std;

int main(int argc, char* argv[]) {
    int n = atoi(argv[1]);   //线程数
    ifstream file("input.txt");
    string word;
    vector<string> words;
    map<string, int> wordCount;
    while (file >> word) {
        for (int i = 0; i < word.length(); i++) {
            if (ispunct(word[i])) {
                word.erase(i--, 1);
            }
        }
        words.push_back(word);
    }
    omp_set_num_threads(n);   //设置线程数
    double starttime = omp_get_wtime();
     #pragma omp parallel for
    for (int i = 0; i < words.size(); i++) {
        #pragma omp critical
        {
            wordCount[words[i]]++;
        }
    }
    double endtime = omp_get_wtime();
    for (auto it = wordCount.begin(); it != wordCount.end(); it++) {
        cout << it->first << ": " << it->second << endl;
    }
    printf("\n并行时间:%lfs\n", endtime - starttime);
    return 0;
}

编译:g++ ./filename.cpp -o ./filename -fopenmp

运行:./filename n     n为设置的线程数

运行结果:

一个进程:

4个进程:

可以看到4个进程比

比一个的慢了差不多一倍,这是由于通讯时间比交耗时造成的。

加速比为:1.914/2.751= 0.6957470010905125

由于通讯时间较长反而没达到加速效果。

OpenMP基本概念
OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C、C++和Fortran。OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用OpenMP降低了并行编程的难度和复杂度。当编译器不支持OpenMP时,程序会退化成普通(串行)程序。程序中已有的OpenMP指令不会影响程序的正常编译运行。

在VS中启用OpenMP很简单,很多主流的编译环境都内置了OpenMP。在项目上右键->属性->配置属性->C/C++->语言->OpenMP支持,选择“是”即可。

OpenMP执行模式
OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。

一个典型的fork-join执行模型的示意图如下:

OpenMP编程模型以线程为基础,通过编译制导指令制导并行化,有三种编程要素可以实现并行化控制,他们分别是编译制导、API函数集和环境变量。

编译制导
编译制导指令以#pragma omp 开始,后边跟具体的功能指令,格式如:#pragma omp 指令[子句[,子句] …]。常用的功能指令如下:

parallel:用在一个结构块之前,表示这段代码将被多个线程并行执行;
for:用于for循环语句之前,表示将循环计算任务分配到多个线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性;
parallel for:parallel和for指令的结合,也是用在for循环语句之前,表示for循环体的代码将被多个线程并行执行,它同时具有并行域的产生和任务分担两个功能;
sections:用在可被并行执行的代码段之前,用于实现多个结构块语句的任务分担,可并行执行的代码段各自用section指令标出(注意区分sections和section);
parallel sections:parallel和sections两个语句的结合,类似于parallel for;
single:用在并行域内,表示一段只被单个线程执行的代码;
critical:用在一段代码临界区之前,保证每次只有一个OpenMP线程进入;
flush:保证各个OpenMP线程的数据影像的一致性;
barrier:用于并行域内代码的线程同步,线程执行到barrier时要停下等待,直到所有线程都执行到barrier时才继续往下执行;
atomic:用于指定一个数据操作需要原子性地完成;
master:用于指定一段代码由主线程执行;
threadprivate:用于指定一个或多个变量是线程专用,后面会解释线程专有和私有的区别。
相应的OpenMP子句为: 


private:指定一个或多个变量在每个线程中都有它自己的私有副本;
firstprivate:指定一个或多个变量在每个线程都有它自己的私有副本,并且私有变量要在进入并行域或任务分担域时,继承主线程中的同名变量的值作为初值;
lastprivate:是用来指定将线程中的一个或多个私有变量的值在并行处理结束后复制到主线程中的同名变量中,负责拷贝的线程是for或sections任务分担中的最后一个线程; 
reduction:用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的归约运算,并将结果返回给主线程同名变量;
nowait:指出并发线程可以忽略其他制导指令暗含的路障同步;
num_threads:指定并行域内的线程的数目; 
schedule:指定for任务分担中的任务分配调度类型;
shared:指定一个或多个变量为多个线程间的共享变量;
ordered:用来指定for任务分担域内指定代码段需要按照串行循环次序执行;
copyprivate:配合single指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中;
copyin:用来指定一个threadprivate类型的变量需要用主线程同名变量进行初始化;
default:用来指定并行域内的变量的使用方式,缺省是shared。
利用omp_set_num_threads()来设置线程数,

利用#pragma omp parallel sections 声明下面大括号中的语句要并行多线程执行;

利用#pragma omp section 分配线程。

看懂下列helloworld的代码对openmp并行就会有一定了解。

 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/664230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能数字资产管理系统,全面提升企业的管理效率

智能数字资产管理系统&#xff0c;能够为企业带来很多成果&#xff0c;提高企业管理效率。让程序简单化&#xff0c;提升组织生产率&#xff0c;可以帮助企业以更有效的方式企业实现目标。 研发背景 智能数字资产管理系统 系统功能 1.可以实现数字资产全生命周期的管理&#…

大厂月薪15K被优化,面试 “吹牛” 入职小厂,月薪25K 好慌...

某大厂员工被优化&#xff0c;面试“吹牛”入职小厂&#xff0c;纠结去不去&#xff0c;心里有点慌。 作为一个从福报厂出来的HR&#xff0c;目前在100多人的小厂当HR总监。面对这种情况已经是见怪不怪了。作为小厂&#xff0c;没有大厂那么严格的背调&#xff0c;所以有些来自…

端口映射的作用?如何在路由器上做端口映射

一、端口映射作用 路由器中设置端口映射的主要作用&#xff0c;就是让Internet上的其他用户&#xff0c;可以访问你路由器下面电脑中的数据(软件、文件)。 当家里的电脑使用路由器上网后&#xff0c;在Internet下的其它电脑、手机等网络设备&#xff0c;将无法自接访问你电脑…

C++ 反汇编简要

摘要&#xff1a;本文主要描述x86_64机器中C代码在汇编中的具体代码。   关键字&#xff1a;cpp,IA32,asm   注意&#xff1a;本书假定你拥有基本的C软件开发能力&#xff0c;能够理解基本的C代码。并且熟悉汇编代码&#xff0c;了解基本的取址模式并且熟悉IA32指令集&…

基于LDA与PCA算法的鸢尾花数据集二维投影比较

目录 1. 作者介绍2. LDA和PCA算法介绍2.1 LDA算法2.2 PCA算法2.3 两个算法的区别与联系 3. 实验过程3.1 数据集介绍3.2 算法流程3.3 核心算法介绍3.4 完整代码3.5 实验结果与分析 1. 作者介绍 王鑫&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生…

70+页实战经验分享,《研发效能红宝书》重磅发布 | 附下载

研发效能提升方法从来没有标准答案&#xff0c;不同角色的人&#xff0c;以不同的目标搭建效能体系的方法千差万别&#xff0c;但又存在互通之处。所以做研发效能更需要多方借鉴&#xff0c;然后因地制宜&#xff0c;找到适合自己的方式。于是&#xff0c;我们汇集业界多位效能…

shell脚本解析 01

一、shell 概述 1.shell 的两层含义&#xff1a; 既是一种应用程序,又是一种程序设计语言 a.作为应用程序&#xff1a; 交互式地解释、执行用户输入的命令&#xff0c;将用户的操作翻译成机器可以识别的语言&#xff0c;完成相应功能。称之为 shell 命令解析器。shell 是用户和…

DreamBooth论文解读

文章目录 摘要问题算法3.1 文生图扩散模型3.2 个性化文生图模型3.3 特定类别先验保留损失 实验评估方式比较消融实验PPL类别先验 应用限制 结论 论文&#xff1a; 《DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation》 project&#xf…

yueyin uart ip 使用说明文档

目录 1 概述2 IP功能3 IP端口4 收发数据时序4.1 Uart_tx接口4.2 Uart_rx接口5 获取IP地址 1 概述 本文用于讲解yueyin IP 的uart ip&#xff08;串口/rs422/rs485/rs232&#xff09;的功能&#xff0c;以及使用说明&#xff0c;方便使用者快速上手。 版本&#xff1a;V1.0.0 编…

行业报告 | 清华大学AIGC发展研究1.0震撼发布!(技术+未来篇)

文 | BFT机器人 01 技术篇 深度学习进化史:知识变轨 风起云涌 已发生的关键步骤&#xff1a; 人工神经网络的诞生 反向传播算法的提出 GPU的使用 大数据的出现 预训练和迁移学习 生成对抗网络 (GAN) 的发明 强化学习的成功应用 自然语言处理的突破 即将发生的关键步骤…

基于matlab对传感器阵列中的扰动和元件故障进行建模(附源码)

一、前言 本示例展示了如何对传感器阵列中的幅度、相位、位置和模式扰动以及晶片故障进行建模。 二、振幅扰动 本节介绍如何在 10 个晶片的均匀线性阵列 &#xff08;ULA&#xff09; 上添加增益或幅度扰动。将扰动视为统计上独立的零均值高斯随机变量&#xff0c;标准差为 0.1…

Linux内核进阶----整体框架及子系统概览

目录 1、概述 2、核心抽象及设计选型 2.1. 对进程和内核的抽象 2.2. 对进程地址空间的抽象 2.3. 支持可重入可抢占的内核 2.4. 放松管控与努力回收 2.5. 单块结构内核动态加载模块 2.6. 为系统中的一切活动打拍子 2.7. 一切皆文件的理念 3、Linux整体架构模块说明 3.…

Pnpm实现Monorepo风格项目搭建

Monorepo是什么 与Monorepo对比的是MutiRepo。对于一个复杂的前端架构通常会有多个npm package组成。repo指的是版本仓库。如果多个package放在一个repo仓库中就叫做monorepo。 目前有不少大型开源项目采用了这种方式&#xff0c;如 Babel&#xff0c;React, Meteor, Ember, …

基于Hexo和Butterfly创建个人技术博客,(12) 定制化博客站点高级功能,如搜索、在线聊天、自定义样式等

Butterfly官方网站&#xff0c;请 点击进入 部分特效来源于网站的总结&#xff0c;请点击进入 本章目标&#xff1a; 选择自己需要的内容&#xff0c;然后加以实现。本文中涉及的修改方式主要包含三种&#xff1a;1、修改源码&#xff1b;2、扩展源码&#xff1b;3、添加插件&a…

项目进度延误怎么办?给项目经理的6个处理提示

有研究调查称&#xff0c;只有2.5%的企业能100%成功完成他们的项目。影响项目成功的因素有很多&#xff0c;但对项目生产力造成严重损失的一个重要方面是项目延误。 无论是同事请病假&#xff0c;还是客户想要返工&#xff0c;许多事情都可能导致项目延误。当发生这些情况&…

桥梁监测系统多少钱?桥梁监测系统组成部分有哪些?

桥梁作为大多数城市和国家的重要设施&#xff0c;为居民提供了交流和沟通的纽带。然而&#xff0c;随着时间的推移、超荷载的运输和不间断的环境影响&#xff0c;桥梁的状态日益恶化。为了更好的了解桥梁的结构状态&#xff0c;保障桥梁的安全性和可靠性&#xff0c;桥梁监测系…

SQL注入第二章节MYSQL手工注入

SQL注入第二章节MYSQL手工注入 2.1 SQL注入之sqli-labs环境搭建 一、SQLi-Labs是什么&#xff1f; SQLi-Labs是一个专业的SQL注入练习平台&#xff0c;适用于GET和POST场景&#xff0c;包含了以下注入&#xff1a; 基于错误的注入&#xff08;Union Select&#xff09; 字符…

信息论/python笔记: 最大信息系数 MIC

1 互信息 sklearn 笔记整理&#xff1a;sklearn.metrics_sklearn中的mean absolute percentage error_UQI-LIUWJ的博客-CSDN博客 2 最大信息系数&#xff08;MIC&#xff0c;Maximal Information Coefficient&#xff09; 2.1 方法介绍 衡量两个变量X和Y之间的关联程度&…

知识蒸馏的说明

本文参考&#xff1a; ChatGPT 温度系数t与top-p, 超参怎么设置最优&#xff1f; - 知乎 知识蒸馏系列&#xff08;一&#xff09;&#xff1a;三类基础蒸馏算法_OpenMMLab的博客-CSDN博客 知识蒸馏算法汇总 - 知乎 知识蒸馏__Old_Summer的博客-CSDN博客 目录 1、 ChatGPT…

一文弄懂mysql事务

首先,什么是事务呢? 事务就是由单独单元的一个或多个sql语句组成, 在这个单元中, 每个sql的语句都是相互依赖的, 而整个单独单元作为一个不可分割的整体存在, 类似于物理当中的原子(一种不可分割的最小单位) 通俗的来讲就是, 事务就是一个整体, 里面的内容要么都执行成功, 要…