游戏服务器工程实践一:百万级同时在线的全区全服游戏

我应该有资格写这篇文章,因为亲手设计过可以支撑百万级同时在线的全区全服类型的游戏服务器架构。

若干年前我在某公司任职时,参与研发过一款休闲类型的游戏,由 penguin 厂独代。研发的时候,p 厂要求我们的游戏服务器要能支撑百万以上的同时在线,并且也要能够支持在 30 分钟内扩容 100 万在线。

在经历了 p 厂好几轮的 TDR (Technical Design Review) 后,游戏稳稳上线了。上线后最高同时在线 (pcu) 到达 30 万左右,虽然没有达到 100 万,但从服务器运行状况来看,完全可以稳稳支撑百万以上的。

做过这种架构之后,再看原神这种大 dau 的开放世界游戏,或者鸣潮这种号称有 3100 万预约的,都不觉得有啥难,反而由于开放世界的游戏偏单机向,服务器负载更小。而像王者荣耀这种 pcu 接近千万级的 moba 也不难,只是个 “开房间类型” 的游戏而已,它的服务器难点主要是在网络同步这一块。

虽然大型互联网应用的规模是远超游戏的,但游戏也有其特殊性,对于延迟特别敏感,并且往往有一部分服务器节点必须是有状态的,所以游戏服务器架构有自己的难点,不能照搬互联网那一套。

本文会介绍这类游戏服务器的架构如何搭建,如何实现水平扩容、高可用、容灾的目标。在具体的部署上,也会提供自建和公有云两种方案。


1. 全区全服

此处提到的全区全服,是指所有玩家在一个大通服里一起游戏,不需要像 mmo 那样,登录后还需要选一个区。

全区全服的游戏,战斗是 “开房间式” 的,匹配够 n 个人就开始一盘游戏,有时候 n 可能为 1,一般的 sns 游戏,io 类游戏,都是全区全服的。

目前世面上几乎所有的全区全服类型的游戏都可以归类为开房间类型的,区别只是房间人数的多少而已。举几个例子:开放世界的,pve 的时候可以理解为单人房间,pvp 的时候是多人房间;棋牌类型的,n个人一桌,这一桌可以定义为一个房间;moba 类型的,像王者,也是几个人一个房间。

btw,棋牌类型的,早期的架构都是房间+桌子,整个游戏分 n 个房间,一个房间分 n 个桌子,一个桌子坐 n 个人。当下已经完全没必要那样设计了,统一抽象成房间就行,更容易做负载均衡。


2. 总体架构

一切的难点都是因为量级太大,当 pcu 到达百万级的时候,水平扩容&负载均衡成为最关键的问题,整个架构的各个组成部分都要设计成可以水平扩容的。除此之外,还要做到高可用、容灾。

2.1 架构图

以下是一个实际可用的服务器架构:


图1:全区全服游戏服务器总体架构


2.2 工作过程

以 “玩家登录并战斗” 为场景,简单说明一下工作过程:


图2:玩家登录并战斗流程

用文字描述就是:

1、客户端通过 sdksvr 完成 sdk 登录授权,获得一个 token;
2、客户端以 token 作为凭证连接上 plazasvr,拉取游戏数据;
3、客户端发送加入战斗请求到 plazasvr,plazasvr 转发给 matchsvr,matchsvr 完成匹配后,从 battlesvr 集群中选择一台 battlesvr 来承担这局战斗;
4、客户端连上分配下来的 battlesvr 进行战斗;


3. 架构说明

以上架构图里展示的,无论是基础的网络负载层、数据层,或是自己开发的游戏服务层,都设计成可以水平扩容的。

下面具体讲下架构的各个组成部分:主要作用,如何做到水平扩容、高可用、容灾。


3.1 网络负载层

这一层主要是为游戏服务层的 sdksvr 集群、plazasvr 集群提供负载均衡的功能。

集群功能自建方案公有云方案
nginx集群为sdksvr提供7层(http)负载均衡dns+nginx集群LB组件的7层LB功能,比如腾讯云的CLB,阿里云的SLB,华为云的ELB
lvs集群为plazasvr提供4层(tcp)负载均衡dns+lvs集群LB组件的4层LB功能,比如腾讯云的CLB,阿里云的SLB,华为云的ELB

说明:

  • 自建方案,主要是运维的活,采用常规的 高可用 + 容灾方案 即可;
  • 自建方案,如果并发连接数特别夸张,需要考虑采用 F5 之类的硬件;
  • 公有云方便很多:弹性更大,上限更高,扩容简单,更稳定,费用可能更低;

3.2 游戏服务器层

这一层由我们自己开发的游戏服务器构成。


3.2.1 各服务器的作用

服务器作用
sdksvr为玩家提供登录、注册、充值、版本更新、停服公告等功能;为外部厂商提供充值回调、推广回调等功能
plazasvr为玩家提供游戏接入点;提供除了战斗之外的所有功能;
battlesvr为玩家提供战斗功能
matchsvr为玩家提供战斗匹配;对 battlesvr 进行调度&负载均衡
managesvr为运营人员提供后台管理功能;为运营人员提供统计数据查看功能

3.2.2 各服务器的特性

服务器面向通讯协议水平扩容负载均衡高可用容灾
sdksvr玩家&外部厂商http支持,无状态web服务器支持,由前置的的nginx集群提供负载均衡支持,冗余部署即可支持,无状态的,宕机不丢数据
plazasvr玩家tcp + protobuf + 长连接支持,用户可连接任意plazasvr接入游戏支持,由前置的lvs集群提供负载均衡支持,冗余部署即可支持,不cache数据,宕机不丢数据
battlesvr玩家(udp or tcp) + protobuf + 长连接支持,battle 可在任一个 battlesvr 运行支持,由 matchsvr 进行匹配调度支持,冗余部署即可不支持,cache了战斗状态,宕机会丢失所在svr上的战斗
matchsvr不接受用户连接不支持不支持支持,冗余部署即可,主备模式支持,不cache数据,宕机不丢数据
managesvr运营人员http支持,无状态web服务器支持,但没必要,若需要可部署前置的nginx集群提供负载均衡支持,冗余部署即可支持,无状态的,宕机不丢数据

3.2.3 plazasvr 实现细节

避免重复登录

用户可以连接到任一个 plazasvr 来接入游戏,但需要避免同个用户登录到多个 plazasvr,这个可以通过在 redis 上记录用户的登录服来避免重复登录,plazasvr 在处理登录前先从 redis 取数据判断,如果已经在别服登录,则先踢了别服的,再登录本服。

自我保护

plazasvr 由网络层的 lvs 负载均衡的,lvs 并不知道 plazasvr 的实际压力,所以它需要自我保护,设定一个合理的人数上限,这个可以通过压测,获得一个 80% 性能消耗的人数阈值。

plazasvr 内部可以维护一个在线人数计数,超过阈值就拒绝连接,而客户端在被拒绝后,应该立刻重新请求,让 lvs 重新负载到别的空闲 plazasvr 上。


3.2.4 battlesvr 实现细节

是否被直连

延迟敏感型的游戏,battlesvr 应该直接暴露给玩家直连,这样可以最大化的减少延迟。

延迟不敏感的,假如交互的数据量很少,也可以把 battlesvr 隐藏起来,由 plazasvr 中转数据。

tcp or udp

延迟敏感型的游戏,比如 moba,fps 等,应该使用 udp,找一个靠谱的 rudp 实现即可,比如 kcp,可以做到 “以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度” [1]。

对于延迟不敏感的,用 udp 或 tcp 都关系不大。

容灾

battlesvr 算是这套架构里面唯一的有状态服务器了,而有状态服务器基本上做不到容灾的,一个 battlesvr 宕机,那么在它上面运行着的 battle 也是无法恢复的。

如果是战斗场景状态少,并且延迟不敏感的游戏,比如棋牌、卡牌,可以考虑把场景状态实时的写入内存数据库(比如 redis)来实现容灾,但比较少游戏这么做。


3.2.5 matchsvr 实现细节

matchsvr 是匹配服务器,它的功能就是接受玩家的匹配请求,把这些玩家放到一个池子里,然后把匹配到一起的 n 个玩家放到某个 battlesvr 上,让它们连上去战斗。工作的时候,它可以把所有玩家的匹配请求写入内存数据库中,再按一定频率从中取玩家出来做匹配。

匹配的工作量并不大,所以 matchsvr 并不需要做水平扩容,只需要做到高可用+容灾就够了。

高可用方面,可以将它设计为 “主备模式”,冗余部署,依赖 etcd 进行选主,当主宕机的时候,备可以选举成为主,接替工作。

容灾方面,由于 matchsvr 不 cache 数据,数据都放在内存数据库中(redis),所以不会丢数据,只要保证好 redis 的高可用+容灾即可,而这方面 redis 是有成熟的方案的。


3.2.6 其他功能服务器

上面列出的服务器完全可以实现基本的玩法了,在有些情况下,可能需要额外增加一些功能服务器,但要慎重,总原则是尽量不要盲目增加。

很多功能,其实围绕数据库去设计就行了,像好友、公会、聊天这些,完全可以用 数据库 + plazasvr 实现的。


3.3 数据层

这里面包含了 mysql,redis,etcd,数据仓库。

etcd 提供服务发现及选主功能,本身负载不重,没所谓 sharding 问题,只要做好奇数节点部署,做到高可用及容灾就行了。

“数据仓库” 这里范指流水日志的存储及统计的基本设施,流水日志包括登录、注册、充值、游戏行为、财富变化等,依靠这些流水日志可以统计出留存,rto等数据报表,可以做用户画像,使用当下成熟的 log 采集+大数据计算方案即可。除了自研,还可以考虑接入第三方的统计,比如 “数数” 等,可能整体成本会更低。

剩下的 mysql 、redis,最主要解决的是 sharding 问题。

mysql 用于存储游戏的业务数据,也可以用其他数据库替代,比如 Posgresql,mongodb。

redis 用于 1、存储游戏运行时数据,比如防止用户重复登录的登录服记录、匹配战斗的用户池;2、大型排行榜;3、一些展示性的 cache 数据。其中 1 跟 2 是有持久化需求的。


3.3.1 mysql

mysql 要实现 sharding,自建跟公有云都有不同的方案。

有三种方式实现 sharding,按位置不同,分为业务层,中间件,数据源。

业务层,即在代码逻辑上自己根据某些 sharding key 进行 sharding,可以是 range base,也可以 hash,但无论怎么做,耦合都是高的,过去的游戏服务器挺多使用这种方式做 sharding 的,但放到当下,其实没必要,有其他更优的方案。

中间件,即在业务代码与数据库之间增加一层代理,这种方案,业务代码不需要做什么改变,只要指定 sharding key 就行了。

数据源,省去中间件,在数据库这一层直接实现 sharding,或者说水平分表,一些新的分布式数据库如 TiDB 就支持动态 sharding。


中间件方式

自建的话,选择不多,这篇文章《ShardingSphere 5.x 系列【3】分库分表中间件技术选型》[2]提到了 ShardingSphere 这款中间件,可以尝试一下,文章里面也对某Cat 进行了批判,跟我的个人体验完全一致,总之,千万不要使用某 Cat。

公有云的话,选择也不多,华为云有一款叫 DDM [3],可以尝试一下。

数据源方式

自建的话,目前看,只有 TiDB 是稍微靠谱的。

公有云的话,腾讯云的 TDSQL for Mysql [4]是可以的, p 厂做游戏还是有经验的,之前我司被独代的游戏,用的就是 p 厂改造的 mysql 引擎 tspider,支持透明的分库分表。

mysql以外

可以考虑 MongoDB,它本身就支持 sharding,并且文档化数据库跟游戏对于数据 keyvalue 用法很匹配。

MongoDB 从 4.2 版本开始支持自定义分片键了,游戏一般不需要范围查询,所以用 uid 作为分片键,且基于 Hash 去做 sharding,可以使用数据分布得很均匀,sharding 效果会很好。


总结起来:

方案中间件数据源
自建ShardingSphereTiDB or MongoDB
公有云华为云的 DDM腾讯云的TDSQL or MongoDB

3.3.2 redis

在本架构中,redis 是比较重要的,存储服务器运行数据的,是需要做持久化的,需要高可用&容灾。数据规模比较大,所以 sharding 是有必要的。

自建的话,可以使用 redis cluster 来实现 sharding。

公有云的话,可以直接使用它们提供的集群版本,基本上各大公有云都有对应实现的,甚至有自研的兼容 redis 协议的性能更高的内存数据库,都是可以使用的,问题不大。

但关于 redis 的数据可靠性,有一点是需要清楚的,就是 redis 即使开了 aof,也不一定能保证在 redis 宕机的时候不丢数据,因为为了性能考虑,aof 通常也是用每秒 fsync 的方式的,所以如果宕机,可能会有 1 秒的数据丢失的。

大排行榜

现在应该比较少策划会做全服排行榜的了,但如果做的话,有一些是需要考虑的。

假设周活几千万人,那么周排行榜也差不多就要几千万人排行,这么巨的数据,是不应该放到集群版的 redis,需要放到单独的 redis 中,并且在删除排行榜的时候,不能够直接用 del 命令,会卡很久的,应该在代码逻辑里循环的分批删除,直到删完。


4. 设计细节

4.1 自动重连&失败重试

服务器虽然运行在内网,但内网之间的连接也可能偶尔出现中断的,服务器一定要能自动重连。

另外,服务器与数据库的连接,也可能偶尔出现中断的,服务器不单要能正常的重连 db,还要做数据写入的失败重试,比如有时候需要在线对数据库做扩容处理,往往会造成1分钟内的读写失败。所以一定要做失败重试,并且要设定合理的重试间隔。


4.2 热更新

无论用什么语言,至少做到配置热更新。

如果用 lua 写逻辑的,至少做到可以热修复 bug,虽然 lua 有闭包,比较难以更新,但已经有办法的,可以使用 debug 库重新绑定 upvalue 的方式生成新闭包。

以上目的都是做到更好的运营,减少服务器重启对玩家的影响。


4.3 能拉就不要推

客户端与服务端的交互,能拉数据的就不要推,否则以后优化会很麻烦。尽量让客户端发 request 来获取数据,不要让服务端主动 push。这样做的好处是,主动权放到客户端那边,它可以根据不同的运行环境做不同的适配,调整拉取数据的时机,或者有选择性的拉取自己需要的数据,这样更灵活。

比如同时有 app 端和 h5 端,而 h5 端要轻量化,有些数据是不需要的,那么它可以自己选择拉或不拉一些数据。


4.4 docker 化

对于架构中无状态的部分,完全可以将它 docker 化,这样在扩容,缩容的时候都更敏捷。


5. 性能与故障排查

5.1 压力测试

无论怎么强调都不过分,只有全面的压力测试,才能确保上线稳定,要尽可能模拟足够多的场景,并且在这个阶段,就要把服务器集群接入 prometheus 之类的,看看各方面的指标是否正常,log 也要接入 log 归档服务,自动识别出 log 报错。


5.2 监控

上线前,就要把整个服务器集群都成功的接入 prometheus 之类的 metrics 工具,除了常规的硬件指标:cpu、内存、硬盘、网络,还有业务相关的指标,比如数据相关的收包量、发包量、广播量,各个服的在线人数,战斗人数,战斗个数,这些都要精确到各个具体的进程上,既要能看大盘,又要能看具体个服。

做好性能监控,是一个服务端主程的基本修养。它能带来几个基本好处:

  • 发现问题,很多东西是测试不出来的,线上才会出问题,指标可以清楚告诉我们哪里运行不正常了。

  • 扩容参考,运营经常会导量,做活动,作为主程,你就要评估,撑不撑得住,要不要提前扩容。

  • 优化参考,无论做什么优化,都要基于数据,不要空想,不要纸上谈兵。


5.3 log

log 对于排查错误,提早发现错误太重要了。对于线上运营的游戏,有几个方面要做好的:

  • 预防问题,要在问题恶化前提前发现,要能在海量 log 中发现一行毫不起眼的报错,无论是业务主动输出,还是被动输出的 stack 报错。

  • 快速诊断,出现问题,要跟时间赛跑,第一时间通过 log 诊断到病根,以最快的速度解决。


另外,log 也可以拿来统计得到一些指标性的数据,比如像 nginx 的 access log,可以拿来统计接口的调用比例。


6. 糟糕的设计

下面列举的都是一些(我认为)糟糕的设计。


6.1 “数据库服务器”

经常看到一些文章里面,画的游戏服务器架构图里面会有 dbsvr 这种东西,它的作用大致是作为 gamesvr 和 db 之间的媒介:gamesvr -> dbsvr -> db 。

其实这是很没必要的做法,dbsvr 的存在只会增加单点故障的风险,直接 gamesvr -> db 就好了。


6.2 用 redis cache 玩家核心数据

这是一个愚蠢的设计(我犯过这个错)。大致做法就是用 redis 完全 cache 玩家数据,读的时候从 redis 先读,读不到就从 mysql 读并写入 redis;写的时候就双写 redis 和 mysql。

这种做法的初衷就是为了应对读多写少,但副作用太大了,挺容易就造成数据不一致的,特别是涉及玩家财富的东西,不一致是很可怕的。

我的建议是,redis 不要拿来 cache 玩家数据,玩家数据应该只存在 mysql 这类数据库中。


6.3 微服务化

实际上,上面的架构已经算是某种程度的微服务化了,只不过粒度很大。游戏服务器一来有状态,二来对于延迟要求特别高,互联网的那套所谓微服务化并不适合套在这里。


7. 参考

[1] skywind3000. kcp. Available at https://github.com/skywind3000/kcp.

[2] 云烟成雨TD. ShardingSphere 5.x 系列【3】分库分表中间件技术选型. Available at https://blog.csdn.net/qq_43437874/article/details/135850829, 2024-02-19.

[3] 华为云. 分布式数据库中间件 DDM. Available at https://www.huaweicloud.com/product/ddm.html.

[4] 腾讯云. TDSQL 水平分表. Available at https://cloud.tencent.com/document/product/557/10521.

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

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

相关文章

Vue学习|Vue快速入门、常用指令、生命周期、Ajax、Axios

什么是Vue? Vue 是一套前端框架,免除原生JavaScript中的DOM操作,简化书写 基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上。官网:https://v2.cn.vuejs.org/ Vue快速入门 打开页面&#xff0…

MySQL事务,视图,用户管理学习笔记【事务概念 | 事务隔离级别 | 设置级别 | 视图 | 用户管理】

博客主页:花果山~程序猿-CSDN博客 文章分栏:MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,事务初…

面试杂谈之clickhouse

clickhouse 之前定时任务读取binlog 批量同步clickhouse kafka 批量给clickhouse灌数据 clickhouse列式数据库,运行时创建库表,加载数据查询数据压缩,磁盘存储,向量化引擎,利用CPU多核并行处理缺少完整的update/del…

【SQL】牛客网SQL非技术入门40道代码|练习记录

跟着刷题:是橘长不是局长哦_哔哩哔哩_bilibili 6查询学校是北大的学生信息 select device_id, university from user_profile where university 北京大学 7查找年龄大于24岁的用户信息 select device_id, gender, age, university from user_profile where age…

开源低代码平台技术为数字化转型赋能!

实现数字化转型升级是很多企业未来的发展趋势,也是企业获得更多发展商机的途径。如何进行数字化转型?如何实现流程化办公?这些都是摆在客户面前的实际问题,借助于开源低代码平台技术的优势特点,可以轻松助力企业降低开…

设计模式-装饰器模式(结构型)

装饰器模式 装饰器模式是一种结构模式,通过装饰器模式可以在不改变原有类结构的情况下向一个新对象添加新功能,是现有类的包装。 图解 角色 抽象组件:定义组件的抽象方法具体组件:实现组件的抽象方法抽象装饰器:实现…

沐风老师3DMAX一键多孔结构建模插件Porous使用方法

​3DMAX一键多孔结构建模插件Porous使用教程 3dMax是大家熟知的3D建模软件之一,其功能非常的强大,在科研绘图领域有着非常广泛的应用,但是由于科研绘图的图形(模型)一般都属于异形结构,手工绘制建模&#x…

mysql设置允许外部ip访问,局域网IP访问

(支持MYSQL8版本) 1. 登录进入mysql;mysql -uroot -p输入密码进入 2. 输入以下语句,进入mysql库,查看user表中root用户的访问 use mysql; select host,user from user; 3. 更新user表中root用户域属性&#xff0c…

Docker核心架构原理的深入分析

一、前言 由于平常工作中对Docker使用还是比较频繁的,但是一般都是基础的功能使用,并未对其核心架构原理做梳理,因此抽空简单总结一下这玩意的一些核心概念点知识,以备后面求职工作时可以更为深入地了解这个容器化工具。 二、Do…

springboot与flowable(2):流程部署

一、创建项目 创建springboot项目添加相关依赖。 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.…

Upscayl:款利用人工智能技术,深度学习算法,实现图像无损放大和增强的强大工具。

Upscayl AI&#xff1a; Upscayl AI是一款基于先进的人工智能技术&#xff0c;特别是深度学习算法开发的图像增强工具。它能够智能地分析并改善图像质量&#xff0c;实现无损放大、细节重建和模糊消除&#xff0c;让老旧、低分辨率或模糊的照片焕发新生&#xff0c;达到高清画…

工程师 - VMware workstation pro个人版现已免费

May 13, 2024 VMware 桌面虚拟机管理程序(VMware Desktop Hypervisors) 使用行业标准桌面管理程序 VMware Workstation Pro for Windows 和 Linux 或 VMware Fusion for Mac 运行 Windows、Linux 和其他虚拟机。 Run Windows, Linux and other virtual machines with VMware Wo…

「51媒体」江苏媒体宣传报道,邀请媒体报道资源汇总

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 江苏作为中国东部的重要省份&#xff0c;拥有丰富的媒体资源&#xff0c;包括电视台、广播电台、报纸以及网络媒体。 电视台 江苏卫视&#xff1a;作为江苏省唯一的省级卫视台&#xff…

Java面试_数据库篇_优化,事务,Mysql

Java面试_数据库篇_优化,事务,Mysql 优化如何定位慢查询方案一: 开源工具方案二: Mysql自带慢日志 如何分析慢SQL语句索引介绍索引聚簇索引和非聚簇索引&#xff0c;回表查询覆盖索引&#xff0c;超大分页优化索引创建的原则索引失效 谈谈sql优化的经验 事务事务特性隔离级别un…

system 和 exec 的区别

在 linux 中&#xff0c;使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下&#xff1a; system 中创建了一个子进程&#xff0c;在子进程中执行用户的命令&#xff0c;子进程执行完毕之后&#xff0c;system 会返回。exec 不会创建子进程&#xff0c;…

跟着大佬学RE(六)

findKey 嗯&#xff0c;就是一个窗口程序&#xff0c;没有输入&#xff0c;flag 应该就藏在程序里面 第一遍自己直接莽做&#xff0c;在string窗口&#xff0c;找到 flag{} 看到标红直接 nop 然后&#xff0c;然后就不知道怎么搞了 这串字符提示不能随便 nop &#xff0c;重新…

虚幻引擎5 Gameplay框架(五)

Gameplay重要类及重要功能使用方法&#xff08;四&#xff09; DeveloperSetting DeveloperSetting是在虚幻引擎中是一个基类&#xff0c;主要用于创建和管理开发者设置相关的类。这类设置允许开发者自定义或调整项目中的各种配置选项&#xff0c;而无需直接修改代码或构建设置…

大模型应用开发框架LangChain

LangChain是什么&#xff1f; 它是针对大语言模型开发的一个开源的抽象框架。下图以github的流行度为例&#xff0c;可以看到langchain在很短的时间流行度达到Pytorch框架的高度&#xff0c;在AI燤火的当下&#xff0c;非常的流行。 上图&#xff0c;可以看到短短不到1年&…

AMD在行动:揭示应用程序跟踪和性能分析的力量

AMD in Action: Unveiling the Power of Application Tracing and Profiling — ROCm Blogs 导言 Rocprof是一款强大的工具&#xff0c;设计用于分析和优化基于AMD ROCm平台上运行的HIP程序的性能&#xff0c;帮助开发者找出并解决性能瓶颈。Rocprof提供了多种性能数据&#x…

每日一题——Python实现PAT乙级1099 性感素数(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 专业点评 时间复杂度分析 空间复杂度分析 综合点评 我要更强 优化点 …