八、性能测试
八、性能测试
8.1 性能测试代码
#include"ConcurrentAlloc.h"// ntimes 一轮申请和释放内存的次数
// rounds 轮次
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{std::vector<std::thread> vthread(nworks);std::atomic<size_t> malloc_costtime = 0;std::atomic<size_t> free_costtime = 0;for (size_t k = 0; k < nworks; ++k){vthread[k] = std::thread([&, k]() {std::vector<void*> v;v.reserve(ntimes);for (size_t j = 0; j < rounds; ++j){size_t begin1 = clock();for (size_t i = 0; i < ntimes; i++){//v.push_back(malloc(16));v.push_back(malloc((16 + i) % 8192 + 1));}size_t end1 = clock();size_t begin2 = clock();for (size_t i = 0; i < ntimes; i++){free(v[i]);}size_t end2 = clock();v.clear();malloc_costtime += (end1 - begin1);free_costtime += (end2 - begin2);}});}for (auto& t : vthread){t.join();}//printf("%u个线程并发执行%u轮次,每轮次malloc %u次: 花费:%u ms\n",//nworks, rounds, ntimes, malloc_costtime);cout << nworks << "个线程并发执行" << rounds << "轮次,每轮次malloc"<< ntimes << "次:" << "花费:" << malloc_costtime << "ms" << endl;//printf("%u个线程并发执行%u轮次,每轮次free %u次: 花费:%u ms\n",// nworks, rounds, ntimes, free_costtime);cout << nworks << "个线程并发执行" << rounds << "轮次,每轮次free"<< ntimes << "次:" << "花费:" << free_costtime << "ms" << endl;//printf("%u个线程并发malloc&free %u次,总计花费:%u ms\n",// nworks, nworks * rounds * ntimes, malloc_costtime + free_costtime);cout << nworks << "个线程并发malloc&free" << nworks * rounds * ntimes<< "次,总计花费:" << malloc_costtime + free_costtime << "ms" << endl;
}// 单轮次申请释放次数 线程数 轮次
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{std::vector<std::thread> vthread(nworks);std::atomic<size_t> malloc_costtime = 0;std::atomic<size_t> free_costtime = 0;for (size_t k = 0; k < nworks; ++k){vthread[k] = std::thread([&]() {std::vector<void*> v;v.reserve(ntimes);for (size_t j = 0; j < rounds; ++j){size_t begin1 = clock();for (size_t i = 0; i < ntimes; i++){//v.push_back(ConcurrentAlloc(16));v.push_back(ConcurrentAlloc((16 + i) % 8192 + 1));}size_t end1 = clock();size_t begin2 = clock();for (size_t i = 0; i < ntimes; i++){ConcurrentFree(v[i]);}size_t end2 = clock();v.clear();malloc_costtime += (end1 - begin1);free_costtime += (end2 - begin2);}});}for (auto& t : vthread){t.join();}//printf("%u个线程并发执行%u轮次,每轮次concurrent alloc %u次: 花费:%u ms\n",// nworks, rounds, ntimes, malloc_costtime);cout << nworks << "个线程并发执行" << rounds << "轮次,每轮次concurrent alloc"<< ntimes << "次:" << "花费:" << malloc_costtime << "ms" << endl;//printf("%u个线程并发执行%u轮次,每轮次concurrent dealloc %u次: 花费:%u ms\n",// nworks, rounds, ntimes, free_costtime);cout << nworks << "个线程并发执行" << rounds << "轮次,每轮次concurrent dealloc"<< ntimes << "次:" << "花费:" << free_costtime << "ms" << endl;//printf("%u个线程并发concurrent alloc&dealloc %u次,总计花费:%u ms\n",// nworks, nworks * rounds * ntimes, malloc_costtime + free_costtime);cout << nworks << "个线程并发concurrent alloc&dealloc" << nworks * rounds * ntimes<< "次,总计花费:" << malloc_costtime + free_costtime << "ms" << endl;
}int main()
{size_t n = 1000;cout << "==========================================================" << endl;BenchmarkConcurrentMalloc(n, 4, 10);cout << endl << endl;BenchmarkMalloc(n, 4, 10);cout << "==========================================================" << endl;return 0;
}
8.2 性能瓶颈分析
现在的内存池运行以上代码的时间:

现阶段我们写的内存池的性能还比不上malloc,所以这样的内存池也将毫无意义,所以我们要进一步分析一下我们的内存池究竟慢在哪里?
利用VS2019编译器自带的在调试按钮下的性能探查器可以获取我们的高并发内存池的性能分析结果,具体操作如下:


点击开始之后稍等一下就能得到以下的性能分析报告:

通过性能分析报告可知性能的瓶颈点主要在于ConcurrentFree函数的调用,耗时的占比最高。




一路点进去就会发现最终的耗时多的罪魁祸首就是在锁的竞争上,因为锁竞争本来在时间成本上就是最多的,所以我们要想提高内存池的性能就应该思考我们该如何减少锁竞争的问题。
相关文章:
八、性能测试
八、性能测试 8.1 性能测试代码 #include"ConcurrentAlloc.h"// ntimes 一轮申请和释放内存的次数 // rounds 轮次 void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds) {std::vector<std::thread> vthread(nworks);std::atomic<size_t&g…...
景芯SoC 芯片全流程培训
【全网唯一】景芯SoC是一款用于芯片全流程培训的低功耗ISP图像处理SoC,采用低功耗RISC-V处理器,内置ITCM SRAM、DTCM SRAM,集成包括MIPI、ISP、CNN、QSPI、UART、I2C、GPIO、百兆以太网等IP,采用SMIC40工艺设计流片。 培训数据包括…...
目标检测后的图像上绘制边界框和标签
效果如图所示,有个遗憾就是CV2在图像上显示中文有点难,也不想用别的了,所以改成了英文,代码在下面了,一定要注意一点,就是标注文件的读取一定要根据自己的实际情况改一下,我的所有图像的标注文件…...
Leetcode: 1. 两数之和 【题解超详细】
前言 有人夜里挑灯看花,有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来。 希望下面的题解可以帮助你们开始 你们的 leetcode 刷题 的 天降之路 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中…...
PHP 通过 Redis 解决并发请求的操作问题
比如PHP收到两个并发的请求A和B,要求只能其中一个请求处理S1操作,另一个请求直接返回失败,可以通过redis去解决: SETNX(SET if Not eXists)是 Redis 中的一个原子命令,用于设置键-值对…...
浅谈信息论和信息编码
目录 背景 信息是什么 信息度量 小白鼠实验 哈夫曼编码 密码学 其它应用 背景 克劳德艾尔伍德香农(Claude Elwood Shannon)出生于 1916 年 美国密歇根州。1936 年毕业于密歇根大学,获得数学和电子工程学士学位。之后,他在麻…...
【测试】笔试02
文章目录 1. 下面不属于软件测试步骤的是2. 关于测试驱动开发,描述错误的是3. 在软件测试中,圈复杂度(Cyclomatic complexity):代码逻辑复杂度的度量,提供了被测代码的路径数量。圈复杂度可通过系统控制流图…...
公司内部网段多管控乱,该如何规范跨网文件传输交换?
古往今来,高筑墙一直是有效的防御措施。从边塞长城到护城河外的高高城墙,都是利用隔离地域的形式实现保护安全域的效果。这样一来,城内的安全域可以在遇到危险时受到有效保护。 在企业网络安全防护方面,网络安全域隔离也是网络安全…...
Ceph入门到精通-OSD waring 设置建议
OSD 以下检查表明 OSD 节点存在问题。 警告 1 在 /var/lib/ceph/osd 中找到的多个ceph_fsid值。 这可能意味着您正在托管许多集群的 OSD 此节点或某些 OSD 配置错误以加入 您期望的集群。 2 设置可能会导致数据丢失,因为如果 未达到最小值,Ceph 将不会确…...
软件测试工程师如何快速理解业务?
1. 阅读需求文档和业务资料 仔细阅读与业务相关的文档和资料对于理解业务至关重要。 需求文档通常描述了软件的功能和用户需求,而业务规范则详细说明了业务流程、规则和标准。 仔细阅读这些文档,你可以了解业务的基本概念、要求和流程。 同时&#x…...
【教程】部署apprtc服务中安装google-cloud-cli组件的问题及解决
#0# 前置条件 已经安装完成node,grunt,node 组件和python pip包等。需要安装google-cloud-cli组件。 Ubuntu安装google-cloud-cli组件 apprtc项目运行需要google-cloud-cli前置组件,且运行其中的dev_appserver.py。 根据google官方的关于安…...
C++——shared_ptr:make_shared的用处,与shared_ptr直接构造的区别
shared_ptr shared_ptr继承自__shared_ptr,其中有两个对象,一个是指向资源的指针,一个是控制块,指向一个引用计数对象。控制块中存储了强引用和弱引用的计数,强引用Uses代表shared_ptr对象的引用计数,弱引…...
【网络安全带你练爬虫-100练】第17练:分割字符串
目录 一、目标1:使用函数分割 二、目标2:使用函数模块 三、目标3:使用正则匹配 一、目标1:使用函数分割 目标:x.x.x.x[中国北京 xx云] 方法:split函数replace函数 1、分割:使用split()方法将…...
Unity 之ToolTip的用法
文章目录 在Unity中,ToolTip是一个在编辑器中使用的UI元素,它提供了鼠标悬停在某个对象或控件上时显示的文本信息。ToolTip通常用于向开发人员提供有关对象、字段、控件或菜单项的附加信息,从而帮助他们更好地理解和使用这些元素。 ToolTip通…...
xsschallenge通关(11-15)
level 11 老规矩,先查看源码,做代码审计: <?php ini_set("display_errors", 0); $str $_GET["keyword"]; $str00 $_GET["t_sort"]; $str11$_SERVER[HTTP_REFERER]; $str22str_replace(">&quo…...
Kubernetes技术--k8s核心技术集群的安全机制RBAC
1.引入 我们在访问k8s的集群的时候,需要经过一下几个步骤: -a:认证 -1).传输安全:对外是不暴露端口:8080,只能够在内部访问,对外使用的是6443端口。 -2).客户端认证的常用几种方式: -https证书 基于ca证书 -https token认证 通过token识别用户 -https <...
【JavaSE】String类
两种创建String对象的区别 String s1 "hello"; String s2 new String("hello");s1是先查看常量池是否有 “hello” 数据空间,如果有就直接指向它,如果没有就创建然后指向它。s1最终指向的是常量池的空间地址。 s2是先在堆中创建空…...
DBMS Scheduler设置重复间隔
参考文档: Database Administrator’s Guide 29.4.5.2 Using the Scheduler Calendaring Syntax The main way to set how often a job repeats is to set the repeat_interval attribute with a Scheduler calendaring expression. See Also: Oracle Database…...
windows的redis配置sentinel
1、先安装好redis主从,参考我的文章,链接如下 redis主从(windows版本)_rediswindows版本_veminhe的博客-CSDN博客 2、然后配置sentinel 参考在windows上搭建redis集群(Redis-Sentinel) 配置时…...
NetMarvel机器学习促广告收益最大化,加速获客
游戏出海的竞争日益激烈,这并非空穴来风。 从2021年第一季度至2022年第四季度,iOS平台的CPI增长了88%,意味着厂商需要花费近两倍的钱才能获取一个新用户。与此同时数据隐私政策持续收紧,更加提高了营销成本。 在成本高涨的当下&…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
