Measure time in C++ OpenMP code

关于利用Openmp中使用的时间函数 Openmp是一项并行化技术,是可以提高串行化程序的运行效率的,但需要使用正确的时间函数来进行衡量。 首先,先提出unix/linux下的内核时间获取函数 1.clock()函数 先看其在MSDN中的定义:Returns the processor time consumed by the program,返回的是处理器执行的时间,也就是说,只要内核中有 阅读详情

引言

最近在利用openMP优化串行程序,将串行程序并行化,这就涉及到并行化后的效果的测量问题,很重要的一个指标就是程序执行时间。

在查阅了相当的资料后发现,很多OpenMP初学者都遇到过使用openMP做并行优化但测量时间并未提升,其实很多时候不是程序本身的bug,或许是工具的bug(血泪的教训呀QAQ)

说一说我遇到的坑。。。 不,你不想说。

昨天老板丢给我一个程序,让我用多线程优化下,我思索了一下决定用openMP试试。一开始使用C++函数库中自带的 clock () 函数,测量原程序中的loop函数的运行时间,结果进行openMP改写后时间并没有减少反而升高了,令我一度怀疑是并行出了问题,花了一下午时间研究openMP并行化,却没成想是测量工具的问题QAQ,后来改成了为了omp_get_wtime()效果明显,实验完成。为了以后少走弯路,在此记录一下。

Measure time in C++ OpenMP code

测量时间的工具有很多,我使用了c++中最简单的clock()函数与OpenMP中的omp_get_wtime(),下面先介绍二者,再进行下对比。

clock()

clock_t clock (void);
Returns the processor time consumed by the program.
The value returned is expressed in clock ticks, which are units of time of a constant but system-specific length (with a relation of CLOCKS_PER_SEC clock ticks per second).

官方文档给出的解释是clock()返回程序的处理器时间,也就是CPU时间。但是这个时间是以系统时钟周期形式返回的,需要除以一个每秒时钟周期数CLOCKS_PER_SEC才能转换为我们所说的real time。

示例代码如下:

#include <time.h>
.....
int main()
{
	clock_t timeStart , timeEnd;
	double processingTime;
	timeStart = clock();
  	for(...)
  	.
  	.
  	timeEnd = clock();
	processingTime = (double) (timeEnd - timeStart) / CLOCKS_PER_SEC;
	return 0;
 }

参考文献:http://www.cplusplus.com/reference/ctime/clock/

omp_get_wtime()

double omp_get_wtime(void);
Returns the elapsed wall clock time in seconds.
The time is measured per thread, no guarantee can be made that two distinct threads measure the same time. Time is measured from some “time in the past”, which is an arbitrary time guaranteed not to change during the execution of the program.

官方文档给出的解释是omp_get_wtime()返回的是在程序执行过程中,从过去的任意一个固定时间点开始所经过的时间,单位秒。

示例代码如下:

#include <time.h>
.....
int main()
{
    	double timeStart, timeEnd;  
    	double elapsedTime;
    	timeStart= omp_get_wtime();  
    	for(...)
    	.
    	.
    	timeEnd= omp_get_wtime();  
    	elapsedTime = timeEnd - timeStart; 
    	return 0;
}

参考文献:https://gcc.gnu.org/onlinedocs/libgomp/omp_005fget_005fwtime.html

二者区别

在查阅了相当的资料后发现,很多人都遇到过这个问题,在此总结一下。

第一个区别

clock()函数测量的是CPU时间,是实实在在CPU运行所花费的时间,对于多核CPU而言,CPU时间是将所有CPU上运行的线程的时间累加得到的。

OMP函数omp_get_wtime()测量的是程序执行所经过的时间,是从一个时间点到另一个时间点所经历的时间。

第二个区别

clock()函数测量的是CPU时间,CPU时间就只包含CPU在某个任务上的实际处理时间,不包含运行时的等待系统资源等等相关延迟。

OMP函数omp_get_wtime()测量的是wall time,包含了运行时的所有延迟因素,是从更宏观的层面上来计算的程序实际执行时间。

参考文献:https://en.wikipedia.org/wiki/Elapsed_real_time

实验教训

随手写个demo测试一下:

#include <stdio.h>
#include <unistd.h>
#include <omp.h>
#include <math.h>
#include <time.h>

int main()
{
        clock_t clock_timer;
        double wall_timer;
        double c[10000];
        for (int nthreads = 1; nthreads <= omp_get_max_threads() - 1; ++nthreads)
        {
                clock_timer = clock();
                wall_timer = omp_get_wtime();
                printf("threads: %d ", nthreads);
                #pragma omp parallel num_threads(nthreads)
                for (int i = 0; i < 10000; i++)
                {
                        for (int j = 0; j < 10000; j++)
                                c[i] = sqrt(i * 4 + j * 2 + j);
                }
                printf("time on clock(): %13.8f s\t", (double) (clock() - clock_timer) / CLOCKS_PER_SEC);
                printf("time on wall: %13.8f s\n", omp_get_wtime()-wall_timer);
        }
        
                return 0;
}

用了一个二重loop,目的是为了扩大循环次数放大时间,以便更好观察结果。

实验环境:测试服务器一共2个8核cpu,共16核,测试1-15个线程下的CPU时间与omp wall-clock时间。
测试结果如下:

threads: 1 time on clock():    1.18000000 s time on wall:    1.18664212 s
threads: 2 time on clock():    2.38000000 s time on wall:    1.18867239 s
threads: 3 time on clock():    3.58000000 s time on wall:    1.19807996 s
threads: 4 time on clock():    4.80000000 s time on wall:    1.20108688 s
threads: 5 time on clock():    6.11000000 s time on wall:    1.22768376 s
threads: 6 time on clock():    7.30000000 s time on wall:    1.23721435 s
threads: 7 time on clock():    8.56000000 s time on wall:    1.23622449 s
threads: 8 time on clock():    9.98000000 s time on wall:    1.26976412 s
threads: 9 time on clock():   11.14000000 s time on wall:    1.27234287 s
threads: 10 time on clock():   12.45000000 s time on wall:    1.33065647 s
threads: 11 time on clock():   13.83000000 s time on wall:    1.35075363 s
threads: 12 time on clock():   15.01000000 s time on wall:    1.27852163 s
threads: 13 time on clock():   16.06000000 s time on wall:    1.25557764 s
threads: 14 time on clock():   17.45000000 s time on wall:    1.27296767 s
threads: 15 time on clock():   19.08000000 s time on wall:    1.35811380 s

可以看到clock()与omp_get_wtime()的区别了吧~~

很久都没更博,以后会多抽出点时间写写,希望能帮到大家o( ̄▽ ̄)ブ
大家一起共同学习哦~~

vcpkg 2024.01 实战:Windows MSVC + CMake 项目集成,3步解决OpenCV依赖 本文详细介绍了如何使用vcpkg 2024.01在Windows MSVC + CMake项目中快速集成OpenCV依赖。通过三个关键步骤:安装vcpkg并集成Visual Studio、使用vcpkg安装OpenCV、配置CMake项目,开发者可以高效解决C++依赖管理问题,特别适合处理像OpenCV这样的复杂库。 阅读详情

相关推荐

VS2012中运用OpenMP测试并行处理效率

VS2012中运用OpenMP测试并行处理效率

wolangjushi的专栏 3602

实验五 高斯算法的OpenMP实现

并行计算和互斥访问的结合:代码中通过并行计算和互斥访问的结合,实现了多线程下的并行求和。互斥访问的性能开销:互斥访问会导致线程之间的竞争和等待,从而引入一定的性能开销。在处理共享变量时,要考虑到互斥访问可能对程序性能的影响,并在必要时寻找更适合的并行算法或数据共享策略。在编写并行代码时,需要注意线程间的数据依赖关系,并确保正确的同步或数据共享机制。函数,测量程序的执行时间。在程序中,我们将此ID作为线程的rank,并据此确定线程的工作范围。线程总数的控制:代码假设并行区域中的线程总数是系统默认的线程总数。

qq_56101688的博客 1012

【信息科学与工程学】计算机科学与自动化—第十五篇 云计算 11 算法篇01

编号类型领域问题问题的数学分析(含几何学/拓扑学/代数学/数论/集合论/离散数学/概率论/统计学/其他)及数值分析及算法分析及参数列表及参数数值设计C/C++/rust/python代码软件(含编译器)及硬件资源需求(CPU/GPU/内存【NAND/DRAM/HBM/其他】/HBM、HDD、SSD、RAID卡、其他)关联知识1工作负载调度数据中心最小化总完成时间/成本。

weixin_49199313的博客 220

openmp测试程序

#include &lt;stdio.h&gt;#include &lt;unistd.h&gt;#include &lt;omp.h&gt;void main() {  int j;  //#pragma omp parallel for  //#pragma omp taskwait  //#pragma omp barrier  //#pragma omp for ordered   //#...

winc的博客 1105

measuresystem

是用VC编写的一个外部采集数据的源程序代码,包括串口通讯方面。

计算字符串的精确象素长度

使用GDI32中API计算字符串的精确象素长度

C++下OpenMP耗时统计

类型的值,表示从某一固定点到当前时间的秒数。因此,你可以在代码的开始和结束点分别调用这个函数,并计算两个时间点之间的差异。函数通常具有微秒(百万分之一秒)级别的精度,但具体精度取决于系统硬件和OpenMP实现。循环开始和结束时的时间。然后通过两者的差值来计算循环的执行时间。这种方法非常直观且易于实现,也适用于多线程并行的场景。在C++中,如果你使用OpenMP进行并行计算,你可以使用。函数来测量代码段的执行时间。以下是一个简单的例子,该例子展示了如何使用。

原来也有北瓜 1226

MPI与OpenMP并行程序设计(C语言版)美国教授写的

《MPI与OpenMP并行程序设计(C语言版)》是美国Oregon州立大学的Michael J.Quinn教授在多年讲授“并行程序设计”课程的基础上编写而成的,主要介绍用C语言,并结合使用MPI和OpenMP进行并行程序设计,内容包括并行体系结构、并行算法设计、消息传递编程、Eratosthenes 筛法、Floyd 算法、性能分析、矩阵向量乘法、文档分类、蒙特卡洛法、矩阵乘法、线性方程组求解、有限差分方法、排序、快速傅立叶变换、组合搜索、共享存储编程、融合OpenMP和MPI以及5个附录。 《MPI与OpenMP并行程序设计(C语言版)》按授课方式安排章节,通过划分、通信、集聚和映射等四步的并行程序设计方法,来解决各种实际的并行性问题,使读者掌握系统化的并行程序设计方法,开发出高效的并行程序。 本书不仅是一本优秀的并行程序设计教材,对广大的相关专业人员也很有参考价值。

并行编程OpenMP基础及简单示例

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

weixin_NineDays66 4万+

基于立创·庐山派K230的红色激光点识别和锁定追踪

本文介绍了一种基于立创・庐山派K230开发板的红色激光点识别与追踪系统。该系统通过摄像头采集图像,采用RGB565格式和Gamma校正进行预处理,利用颜色阈值筛选实现红色激光点检测。核心追踪算法采用状态机设计,包含未锁定和已锁定两种状态,通过计算欧氏距离判断目标连续性,并具有丢失计数机制确保稳定性。系统通过UART接口以自定义二进制协议输出坐标数据,同时提供可视化反馈。该方案在800×480分辨率下实现了实时、稳定的单目标追踪,具有检测精度高、响应速度快的特点,适用于工业定位和机器人导航等嵌入式视觉应用场景

m0_73738367的博客 1653

linux入侵排查-综合日志分析

2.分析攻击者首次成功登录web管理后台的时间 还可以知道攻击者可能是通过10.2.4.11这个跳板服务器跳过来的,然后我们继续排查,可以发现日志中POST请求大多都是1047字节,然后往后大多是300字节,POST请求的响应状态码有200和302这两个,其中的302是爆破成功后持续爆破产生的日志,再1047字节和300字节中间夹着一个978字节,就是200响应和302响应的中间。7.分析攻击者留下的持久化后门的时间和后门执行情况 排查计划任务,发现有一个计划任务还是被加密的,应该是反弹shell的。

chinese_cabbage0的博客 644

OpenMP中的常用函数

在OpenMP的Runtime Library中有一些常用的函数,有些函数已经在前面的例子中使用过,现在集中说明这些常用的函数以及用法。 1、设置线程数目 其定义如下: voidomp_set_num_threads(int num_threads); 通过该函数来指定其后用于并行计算的线程数目,其中参数num_threads就是指定的线程数目。 2、获取线程数目 其定义如下: in...

yuanlanxiaup 391

STM32单片机语音提示盲人拐杖整点报时夜间警示超声波测距

STM32单片机语音提示盲人拐杖整点报时夜间警示超声波测距 关键词:语音提示盲人拐杖 整点报时 超声波测距拐杖

LS840233684的博客 2047

OpenMP(3) omp_get_wtime 函数

omp_get_wtime函数可以返回从某个特殊点所经过的时间,单位秒double omp_get_wtime( );返回值:返回从任意一个一致点所经过的时间,单位秒。这个时间点在程序运行过程中必须有一致性,这样才能实现后续比较。例子:// omp_get_wtime.cpp // compile with: /openmp #include "omp.h" #include #...

liuxingrui4p的专栏 1万+

Kali使用Metasploit内、外网渗透windows系统

Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具。当H.D. Moore在2003年发布Metasploit时,计算机安全状况也被永久性地改变了。 一、(内网渗透)内网英文缩写WAN;内网又称局域网 局域网的覆盖范围一般是方圆几千米之内,其具备的安装便捷、成本节约、扩展方便等特点使其在各类办公室内运用广泛。局域网可以实现文件管理、应用软件共享、打印机共享等功能,在使用过程当中,通过维护局域网网...

QQ670663的博客 2万+

激光雷达测距方式全解析:ToF、三角测距和FMCW到底怎么选?

本文深度解析激光雷达三种主流测距方式(ToF、三角测距和FMCW)的技术原理、环境适应性和成本模型,提供场景化选型决策指南。通过对比各技术在精度、抗干扰能力和维护成本等方面的表现,帮助工程师在自动驾驶、工业检测和消费电子等领域做出最优选择。

qqq44的博客 720

omp_get_wtime()

omp_get_wtime()

DDDDD的博客 1559

ESP32S3开发实战:从Vscode+IDF环境配置到OpenOCD单步调试全流程

本文详细介绍了ESP32S3开发环境的完整搭建流程,重点讲解如何在Vscode中配置ESP-IDF开发框架,并利用OpenOCD工具实现硬件单步调试。内容涵盖从环境准备、工程创建、代码烧录到高级调试技巧的全方位实战指南,旨在帮助开发者快速掌握ESP32S3的高效开发与调试方法。

weixin_29168813的博客 208

omp计算时间(高精度)

#include #include using namespace std; const int MAX = 1e8; int *data, *temp, N; void merge(int l1, int r1, int r2) { int top = l1, p = l1, q = r1; while (p < r1 || q < r2) { if (

樱花满地集于我心,楪舞纷飞祈愿相随 1461

电阻的基本原理、参数、应用与选型

电阻的基本原理、电阻的分类、参数,应用与选型,0欧姆电阻的介绍等。

luobeihai的博客 1万+

基于MATLAB的井筒多相流模拟

井筒多相流的模拟可以基于不同的数学模型和计算方法。其中,最常用的模型之一是多相流模型,它基于质量守恒、动量守恒和能量守恒等原理,描述了流体在井筒中的流动行为。对于井筒多相流的模拟和分析可以帮助我们理解和优化油气田开发过程中的流体行为,从而提高产量和效率。在本文中,我们将介绍如何使用MATLAB进行井筒多相流的模拟,并提供相应的源代码。需要注意的是,以上示例是一个简化的模拟,仅用于演示如何使用MATLAB进行井筒多相流模拟。实际应用中,我们需要考虑更多的物理过程和参数,并使用更复杂的数值方法和模型进行模拟。

AtdiHtml的博客 706

OpenMP: OpenMP测试程序

#include #include int main(int argc, char * argv[]) { int nthreads, tid, x; int nthrds = 4; x = 0; omp_set_num_threads(nthrds); #pragma omp parallel private(tid) { tid = omp_get_th

Augusdi的专栏 3205

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C++ OpenMP并行编程笔记

C++ OpenMP并行编程笔记

晚来天欲雪,能饮一杯无? 2214

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++ 常用时间获取函数汇总

另外ros还有睡眠和指定频率循环的功能: 还可以使用 比 更灵活。具体参见:https://www.ncnynl.com/archives/201701/1284.html 法三: omp 基于OpenMP,没有类的封装,用起来更直观一些。(可能效率也更高点?) 测试1 rate=100Hz rate=1000Hz rate=10000Hz rate=50000Hz rate=100000Hz 可以看到,随着频率增大,三种方法的时间都不怎么准了(当然r.sleep应该也不准了……),其中chrono最差

~勿据散客~的博客 3551

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: Linux Ubuntu 安装MPICH3.2.1
下一篇: 部署cloudsim时出现bugs的修复记录
一只程序miao
博客等级 码龄12年 16粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值