Koordinator 异构资源/任务调度实践

2023-11-06

前言

Koordinator 是阿里云基于过去我们建设的统一调度系统中积累的技术和实践经验,对外开源了新一代的调度系统。Koordinator 支持 Kubernetes 上多种工作负载的混部调度。它的目标是提高工作负载的运行时效率和可靠性(包括延迟敏感型负载和批处理任务)。Koordinator 不仅擅长混部场景,也同样支持大数据、AI 训练等任务调度场景。本文分享了使用 Koordinator 支持异构资源管理和任务调度场景的实践经验。

AI/LLMs 带来新机遇和新挑战

从 2022 年 11 月 ChatGPT 发布到现在,ChatGPT 所引起的关注、产生的影响可能已经超越了信息技术历史上的几乎所有热点。众多业界专家都被它征服,比如阿里云 CEO 张勇的看法是:“所有行业、应用、软件、服务,都值得基于大模型能力重做一遍。”NVIDIA CEO 黄仁勋称它带来了 AI 的 iPhone 时刻。ChatGPT 开启了新的时代,国内外的企业和科研机构纷纷跟进,几乎每周都有一个甚至多个新模型推出,从自然语言处理、计算机视觉到人工智能驱动的科学研究、生成式 AI 等,应用百花齐放;大模型成为业务提效和打开下一个增长点的关键。同样对于云计算、基础设施、分布式系统的需求也扑面而来。

为支撑百亿级、千亿级别参数量的大模型训练需求,云计算和基础设施需要提供更强大、可扩展的计算和存储资源。大模型训练依赖的的核心技术之一是分布式训练,分布式训练需要在多个计算节点之间传递大量的数据,因此需要一个带宽更高、延迟更低的高性能网络。为了发挥计算、存储和网络资源的最佳效能,保障训练效率,调度和资源管理系统需要设计更合理的策略。在此基础上,基础设施还需要在可靠性上持续增强,具备节点故障治愈和容错能力,确保训练任务的持续运行。

大模型训练离不开异构计算设备,典型的就是我们熟知的 GPU。在 GPU 领域,NVIDIA 仍然占据着主导地位,其他厂商如 AMD 和国内的芯片制造商的机会在努力追赶。以 NVIDIA 为例,其强大的产品设计能力、扎实的技术实力和灵活的市场策略使其能够快速推出更优秀的芯片,但产品间的架构差异较大,例如 NVIDIA A100 型号和 NVIDIA H100 型号的系统架构差异十分明显,使用方式上也存在许多需要注意的细节,这给上层的调度系统和资源管理系统带来了不小的挑战。

Koordinator+KubeDL 的强强联合

我们在阿里云支撑的大模型训练场景中,使用了 Koordinator 来解决基本的任务调度需求和异构设备资源管理需求。同时,使用 KubeDL 管理训练作业生命周期和训练作业排队调度需求。

Koordinator 不仅擅长混部调度场景,还针对大数据、AI 模型训练场景,提供了包括弹性 Quota 调度、Gang 调度等通用的任务调度能力。此外,它还具备精细化的资源调度管理能力,不仅支持中心化分配 GPU,还能感知硬件系统拓扑分配资源,同时支持 GPU&RDMA 的联合分配和设备共享能力。

我们选择使用 KubeDL 来管理训练作业生命周期,是因为它不仅在支撑了内部大量 AI 领域相关场景,而且得益于其优秀的设计和实现都十分优秀,可运维性、可靠性和功能扩展性都非常出色,自身是一个统一的 controller,可以支持多种训练工作负载,如 TensorFlow、PyTorch、Mars 等。此外,它还可以适配不同调度器提供的 Gang 调度能力,可以帮助已经使用 KubeDL 项目的存量场景平滑的切换到 Koordinator;KubeDL 还内置了一个通用的作业排队机制,可以有效解决作业自身的调度需求。

Koordinator 和 KubeDL 的强强联合,可以很好的解决大模型训练的调度需求。

Job 调度

Job 是一种更高层次的抽象,通常具有特定的计算任务或操作。它可以分割成多个子任务并行完成,也可以拆分成多个子任务协作完成。通常 Job 不会依赖其他的工作负载,可以独立的运行。而且 Job 比较灵活,在时间维度、空间维度、或者资源方面的约束都比较少。

Job 排队

Job 同样需要经过调度程序调度,这也就意味着 Job 同样在调度时需要排队。那为什么需要排队呢?或者说我们可以通过排队解决哪些问题?

是因为系统中的资源有限的,我们的预算也是有限的,而 Job 的数量和计算需求往往是无限的。如果不进行排队和调度,那些计算需求较高或者执行时间较长的 Job 就会占用大量的资源,导致其他 Job 无法获取到足够的资源进行计算,甚至可能导致集群系统崩溃。

因此,为保证各个 Job 能够公平的获得资源,避免资源争夺和冲突,就需要对 Job 进行排队和调度。

我们使用 KubeDL提供的通用的 Job 排队和调度机制解决这个问题。KubeDL 因为本身就内置支持了多种训练工作负载,因此它天然支持按照 Job 粒度进行调度;并且它具备多租户间的公平性保障机制,减少 Job 间的资源争夺和冲突,排队和调度的过程中,KubeDL 根据 Job 的计算需求、优先级、资源需求等因素进行评估和分配,确保每个 Job 都能够得到合适的资源进行计算。KubeDL 支持多种扩展插件,如 Filter 插件,Score 插件等,可以进一步扩展其功能和特性满足不同场景的需求。

弹性 Quota

Job 排队要解决的核心问题之一是资源供给的公平性,一般在调度系统中都是通过弹性 Quota 机制来解决。

弹性 Quota 机制要解决的几个核心问题:首先是保障公平性,不能让某一些任务的资源需求过高导致其他任务被饿死,应尽量让大部分任务都能得到资源;其次需要有一定的弹性能力,能够把空闲的额度共享给当下更需要资源的任务,同样还要能够在需要资源时,把共享出去的资源拿回来,这意味还需要提供具备灵活的策略满足不同场景的需求。

Koordinator 实现了弹性 Quota 调度能力,可以保障租户间的公平性。我们在设计之初就考虑兼容 scheduler-plugins 社区项目中定义的 ElaticQuota CRD,这样方便存量的集群和用户可以平滑的过度到 Koordinator。

另外,我们不仅是兼容 ElasticQuota 原有按照 Namespace 管理 Quota 的能力,还支持按照支持按照树形结构进行管理,可以跨 Namespace。这样的方式可以很好的支持一个复杂的组织的额度管理需求,比如一家公司里多个产品线,每个产品线的预算和使用情况都不一样,都可以转为 Quota 进行管理,并借助弹性 Quota,把暂时没有用到的空闲资源通过额度的形式临时共享给其他部门使用。

Coscheduling

当一个 Job 经过排队被调度后,Job Controller 会创建出一批子任务,对应到 K8s,就是一批 Pod。这些 Pod 往往需要协调一致的启动运行。这也就要求调度器在调度时一定要按照一组 Pod 分配资源,这一组 Pod 一定都可以那可以申请到资源或者一旦有一个 Pod 拿不到资源都认为是调度失败。这也就是调度器需要提供的 All-or-Nothing 调度语义。

如果我们不这样按照一组调度,会出现因为多个作业在资源调度层面出现争抢,是有可能出现资源维度的死锁,即至少两个 Job 会出现拿不到资源的情况,即使原本空闲资源足够其中一个 Job 运行的,也会拿不到。

比如下图中,Job A 和 Job B 同时创建一批 Pod,如果不在中间的 Scheduling Queue 进行排序而是随意的调度,就会出现 Job A 和 Job B 的 Pod 各持有了一部分节点的部分资源,如果此时集群资源紧张,很有可能 Job A 和 Job B 都可能拿不到资源。但如果排序后,我们尝试先让其中一个 Job 的 Pod 先一起尝试优先分配资源,那么至少保障一个 Job 可以运行。

当一个 Job 切分的一组 Pod 非常大时,而集群内的资源又不是十分充足,或者 Quota 不是很多时,可以把这样的一组 Pod 切分成更多个子组,这个切割的大小以能运行任务为基础,假设一个 Job 要求最小切割粒度是每组 3 个 Pod,那么这个最小粒度,一般在调度域中称为 min available。

具体到 AI 模型训练领域,一些特殊的 Job 比如 TFJob,它的子任务有两种角色,这两种角色在生产环境中,也是需要设置不同的 min available 的。这种不同角色的区分的场景还有可能要求每个角色的 min available 都满足时才可以认为符合 All-or-Nothing 语义。

Koordinator 内置了 Coscheduling 调度能力,它兼容社区的 scheduler-plugins/coscheduling 定义 PodGroup CRD,还支持把多个 PodGroup 联合调度,这样就可以支持按角色设置 min available 场景。Koordinator 实现了一个 KubeDL Gang Scheduler 插件,这样就可以和 KubeDL 做集成一起支撑这类调度场景。

精细化设备管理

K8s 设备管理的局限性

K8s 是通过 kubelet 负责设备管理和分配,并和 device plugin 交互实现整套机制,这套机制在 K8s 早期还是够用的,其他厂商如 AMD 和国内的芯片制造商也抓住机会努力追赶。

kubelet 与 device plugin 协作流程

首先 K8s 只允许通过 kubelet 来分配设备,这样就导致无法获得全局最优的资源编排,也就是从根本上无法发挥资源效能。比如一个集群内有两台节点,都有相同的设备,剩余的可分配设备数量相等,但是实际上两个节点上的设备所在的硬件拓扑会导致 Pod 的运行时效果差异较大,没有调度器介入的情况下,是可能无法抵消这种差异的。

其次是不支持类似 GPU 和 RDMA 联合分配的能力。大模型训练依赖高性能网络,而高性能网络的节点间通信需要用到 RDMA 协议和支持 RDMA 协议的网络设备,而这些设备又和 GPU 在节点上的系统拓扑层面是紧密协作的,比如下面这张图是 NVIDIA 的 A100 型号机型的硬件拓扑图,我们可以看到,PCIe Switch 下挂了 GPU 和高性能网卡,我们需要就近分配这两个设备,才能做到节点间通信的低延迟。而且这里比较有意思的是,当如果需要分配多个 GPU 时,如果涉及到了多个 PCIe Switch,就意味着需要分配多个网卡,这就和 K8s 的另一个限制有关系,即声明的资源协议是定量的,而不是随意变化的,也就是说用户实际上也不知道这个 Pod 需要多少支持 RDMA 的网卡,用户只知道要多少个 GPU 设备,并期望就近分配 RDMA 的网卡而已。

而且 kubelet 也不支持设备的初始化和清理功能,更不支持设备的共享机制,后者在训练场景一般用不到,但在线推理服务会用到。在线推理服务本身也有很明显的峰谷特征,很多时刻并不需要占用完整的 GPU 资源。

K8s 这种节点的设备管理能力一定程度上已经落后时代了,虽然现在最新的版本里支持了 DRA 分配机制(类似于已有的 PVC 调度机制),但是这个机制首先只在最新版本的 K8s 才支持,但实际情况是还有大量存量集群在使用,并且升级到 K8s 最新版本也并不是一个小事情,所以我们得想其他办法。

Koordinator 精细化设备管理机制

我们在 Koordinator 中提出了一种方案,可以解决这些问题,做到精细化的资源调度。

Koordinator 精细化设备管理机制

从上面的图中可以看到,用户创建的一个 Pod,由 koord-scheduler 调度器根据 koordlet 上报的 Device CRD 分配设备,并写入到 Pod Annotation 中,再经 kubelet 拉起 Sandbox 和 Container,这中间 kubelet 会发起 CRI 请求到 containerd/docker,但在 Koordinator 方案中,CRI 请求会被 koord-runtime-proxy 拦截并转发到 koordlet 内的 GPU 插件,感知 Pod Annotation 上的设备分配结果并生成必要的设备环境变量等信息返回给 koord-runtime-proxy,再最终把修改后的 CRI 请求转给 containerd/docker,最终再返回给 kubelet。这样就可以无缝的介入整个容器的生命周期实现自定义的逻辑。

Koordinator Device CRD 用来描述节点的设备信息,包括 Device 的拓扑信息,这些信息可以指导调度器实现精细化的分配逻辑。

Koordinator Device 对象

Future: NRI 模式

前面提到了 Koordinator 单机侧依靠 koord-runtime-proxy 协作完成设备信息注入,我们自己也意识到,koord-runtime-proxy 这种方式其实不太好在大家的集群内落地。这涉及到修改 kubelet 的启动参数问题。

所以 Koordinator 社区后续会引入 NRI/CDI 等机制解决这个场景的问题。这块工作正在和 Intel 相关团队共建。

NRI/CDI 是 containerd 支持的一种插件化机制。其部署方式有点类似于大家熟悉的 CNI,支持在启动 Sandbox/Container 前后获得机会修改参数或者实现一些定制逻辑。这相当于是 containerd 内置的 runtimeproxy 机制。

GPU&RDMA 按照硬件拓扑联合分配

前面也提到,大模型训练不仅仅只用到了 GPU,还依赖 RDMA 网络设备。要确保 GPU 和 RDMA 之间的延迟尽可能的低,否则会因为设备间的延迟放大到整个分布式训练网络中,拖慢整体的训练效率。

这就要求在分配 GPU 和 RDMA 时需要感知硬件拓扑,尽可能就近分配这种设备。尝试按照同 PCIe,同 NUMA Node,同 NUMA Socket 和 跨 NUMA 的顺序分配,延迟依次升高。

而且我们还发现同一个硬件厂商的不同型号的 GPU,它们的硬件系统拓扑是不一样的,这就要求我们的调度器需要感知这些差异。比如下图是 NVIDIA A100 型号的 System Topology 和 NVIDIA H100 的一个简单的设备连接图。

NVIDIA A100 System Topology

NVIDIA A100 GPU 之间的 NVLINK 联通方式和 NVIDIA H100 型号就不一样,NVSwitch 的数量也不一样,这种差异就会给使用方式带来很大的差异。

NVIDIA H100

NVIDIA-based system 在多租模式下的差异

NVIDIA H100 GPU 在多租 VM 场景下的特殊之处,多个 GPU 之间联通需要操作 NVSwitch 才可以实现。

在多租场景中,NVIDIA 为保障安全,会通过 NVSwitch 管理 NVLink 的隔离状态,并且要求只能由授信的软件操作 NVSwitch。这个授信软件是可以自定义的。

NVIDIA 支持多种模式,一种是 Full Passthrough 模式,这种模式把 GPU 和 NVSwitch 都直通到 VM 的 Guest OS,这样做的好处是使用起来很简单,但代价是当 GPU VM 多了,NVLINK 的带宽会减少(原文:Reduced NVLink bandwidth for two and four GPU VMs)。

另一种称为 Shared NVSwitch 多租户模式,它只要求把 GPU 直通到 Guest OS,然后通过一个特殊的 VM,称为 Service VM 管理 NVSwitch,并通过 ServiceVM 调用 NVIDIA Fabric Manager 激活 NVSwitch 实现 GPU 间通信。这种模式就不会出现因为 Full Passthrough 模式的弊端,但使用方式明显要更复杂一些。这种特殊的硬件架构和使用方式,还导致在分配 GPU 时有一些额外的要求。NVIDIA 定义了哪些 GPU 设备实例可以组合一起分配,比如用户申请分配 4个 GPU,那必须是按照规定的 1,2,3,4 号一起或者 5,6,7,8 一起分,否则就会导致 Pod 无法运行。

这种特殊的分配方式的背后原因我们不得而知,但分析这些分配约束可以发现,厂商规定的这种组合关系正好符合硬件系统拓扑结构,也就是可以满足前面讲到的 GPU&RDMA 联合分配期望的分配结果。

NVIDIA H100 System Topology

点击立即免费试用云产品 开启云上实践之旅!

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Koordinator 异构资源/任务调度实践 的相关文章

  • DAMA-DMBOK2重点知识整理CDGA/CDGP——第2章 数据处理伦理

    目录 一 分值分布 二 重点知识梳理 1 语境关系图 2 引言 3 业务驱动因素 4 基本概念 一 分值分布 CDGA 2分 2单选 CDGP 0分 不考 二 重点知识梳理 1 引言 预警关系图 数据处理伦理定义 如何以符合道德准则及社会责
  • 北森,SaaS风口上的「新范式」

    在单纯的战略表象背后 成立19年 北森在每一个节点做选择的核心驱动力是什么 这家公司是否拥有自己内部的 组织密码 作者 皮爷 出品 产业家 2013年 纪伟国决定要去美国 取取经 和他同行的还有参与了北森A轮融资的经纬等机构投资人 对于北森
  • DevOps极速入门丨Gitlab丨Jenkins丨harbor丨CICD丨自动化丨运维开发

    DevOps极速入门丨Gitlab丨Jenkins丨harbor丨CICD丨自动化丨运维开发 一 DevOps介绍 软件开发最开始是由两个团队组成 开发计划由开发团队从头开始设计和整体系统的构建 需要系统不停的迭代更新 运维团队将开发团队的
  • 云原生之深入解析如何限制Kubernetes集群中文件描述符与线程数量

    一 背景 linux 中为了防止进程恶意使用资源 系统使用 ulimit 来限制进程的资源使用情况 包括文件描述符 线程数 内存大小等 同样地在容器化场景中 需要限制其系统资源的使用量 ulimit docker 默认支持 ulimit 设
  • 干货下载丨不分业态、不关注核心需求,怎么做得好项目管理?!

    项目管理 装备制造业的破局利刃 对于装备制造行业而言 每一笔订单都是 非标定制 小批量制造 这种特性决定了其行业企业普遍存在 新品开发周期长 生产效率低 质量不稳定 交货期不稳定 成本预算难控制 非标品报价慢 等问题 如何提升企业的管理水平
  • 中国首家!腾讯云入选Gartner®视频平台服务市场指南代表厂商

    近日 Gartner正式发布 Market Guide for Video Platform Services 视频平台服务市场指南 下称 指南 凭借领先的音视频技术和产品组合优势 腾讯云成为中国首家且唯一入选的代表厂商 腾讯云VPS一站式
  • Docker与云计算平台集成:AWS、Azure、GCP完全指南

    Docker和云计算平台的结合 如AWS Amazon Web Services Azure Microsoft Azure 和GCP Google Cloud Platform 为现代应用的构建和部署提供了巨大的便利性 本文将深入研究如何
  • 什么是微服务

    微服务是一种架构风格 它把一个大型的复杂软件应用划分为一系列小的服务 每个服务都具有单一的功能 运行在其自己的进程中 并通常基于不同的编程语言和框架 这些服务之间通过轻量级通信机制相互通信 这种通信机制基于HTTP协议 微服务架构风格使得系
  • 如何利用 Kubernetes 的新 CronJob API 进行高效的任务调度

    Kubernetes 的 CronJob API 是在云原生环境中自动执行常规任务的关键功能 本指南不仅引导您完成使用此 API 的步骤 还说明了它非常有用的实际用例 先决条件 正在运行的 Kubernetes 集群 版本 1 21 或更高
  • 阿里云一二级域名配置

    一级域名配置 二级域名配置
  • 什么是微服务

    微服务是一种架构风格 它把一个大型的复杂软件应用划分为一系列小的服务 每个服务都具有单一的功能 运行在其自己的进程中 并通常基于不同的编程语言和框架 这些服务之间通过轻量级通信机制相互通信 这种通信机制基于HTTP协议 微服务架构风格使得系
  • k8s集群使用calico网络组件

    一 前言 k8s的网络组件可以使用flannel或者calico两种 flannel的配置比较简单 但是性能还是calico会更高一点 所以现在来介绍以下calico网络组件的部署 二 部署 k8s集群版本对calico的版本也有对应要求
  • CloudPulse:一款针对AWS云环境的SSL证书搜索与分析引擎

    关于CloudPulse CloudPulse是一款针对AWS云环境的SSL证书搜索与分析引擎 广大研究人员可以使用该工具简化并增强针对SSL证书数据的检索和分析过程 在网络侦查阶段 我们往往需要收集与目标相关的信息 并为目标创建一个专用文
  • 微服务常见的配置中心简介

    微服务架构中 常见的配置中心包括以下几种 Spring Cloud Config Spring Cloud Config是官方推荐的配置中心解决方案 它支持将配置文件存储在Git SVN等版本控制系统中 通过提供RESTful API 各个
  • 微服务常见的配置中心简介

    微服务架构中 常见的配置中心包括以下几种 Spring Cloud Config Spring Cloud Config是官方推荐的配置中心解决方案 它支持将配置文件存储在Git SVN等版本控制系统中 通过提供RESTful API 各个
  • promethues grafana 安装和使用

    文章目录 1 promethues安装 2 node exporter安装 3 grafana安装 4 配置promethues监控node节点 5 grafana操作 外传 Docker 镜像下载地址 https hub docker c
  • 从不同维度的调研数据,看企业数字化转型

    数字化转型逐渐成为企业增长和价值创造的新引擎 然而 在复杂的背景下 企业数字化转型也面临着前所未有的挑战和机遇 未来 我们还能做些什么 怎么做 这成为了各企业高管当前亟需厘清的问题 企业做数字化转型的原因 总体来看 大部分受访企业做数字化转
  • Kubernetes (十一) 存储——Secret配置管理

    一 简介 从文件创建 echo n admin gt username txt echo n westos gt password txt kubectl create secret generic db user pass from fi
  • Kubernetes (十二) 存储——Volumes配置管理

    一 卷的概念 官方地址 卷 Kubernetes https v1 24 docs kubernetes io zh cn docs concepts storage volumes 二 卷的类型及使用 emptyDir卷 1 创建编辑文件
  • Kubernetes (十三) 存储——持久卷-动静态分配

    一 简介 二 NFS持久化存储步骤 静态分配 1 集群外主机用上次nfsdata共享目录中创建用来测试的pv 1 3 目录 用来对三个静态pv 2 创建pv的应用文件 vim pv yaml apiVersion v1 kind Persi

随机推荐

  • python的类相关知识总结

    下面位一段类代码块 class Car def init self make model year self make make self model model self year year self odometer reading 4
  • 语音交互有哪些优势与劣势?

    转载自公众号 谈人工智能 转载请联系授权 语音交互是指人与人 人与设备之间 通过自然语音进行信息传递的过程 人与人之间通过语音来传递信息 交流感情等等 其实就是一种最基本的人与人之间的语音交互 为什么VUI这个概念 Voice User I
  • matlab欧拉法截断误差,一阶常微分方程欧拉法与梯形公式局部截断误差与p阶精度Range.PPT...

    一阶常微分方程欧拉法与梯形公式局部截断误差与p阶精度Range 一阶常微分方程 欧拉法与梯形公式 局部截断误差与p阶精度 Range Kutta公式 常微分方程MATLAB求解 数值分析 23 例1 一阶常微分方程 求解区域 0 x 1 5
  • (译)神经网络基础(1):Logistic 回归

    点击阅读原文 翻译 huangyongye 前言 本文在翻译过程中 为了便于理解 某些句子可能和原文有一定的出入 但是整体上没有太大的改动 由于本人水平有限 翻译或者理解不对的地方 欢迎指正 不胜感激 Logistic 回归 本例子包括以下
  • ThreadPoolTaskScheduler 简单的记录

    initializeBean方法 protected Object initializeBean final String beanName final Object bean Nullable RootBeanDefinition mbd
  • 关于OkGo中由于响应码不同返回的错误提示无法获取解决方案

    使用okgo过程中发现原有的callBack无法再onError方法中返回错误信息内容 所以可以通过自定义callBack 方法来获取响应的内容 eg package com lide mygit public class MainActi
  • java怎么校验字符串为正数或者两位小数

    可以使用正则表达式来校验字符串是否为正数或两位小数 下面是一个例子 public static boolean isPositiveNumberOrTwoDecimalPlaces String str String pattern 0 9
  • 通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败“常见问题的解决方案

    问题 服务器突然显示连接失败 通过端口 1433 连接到主机 localhost 的 TCP IP 连接失败 错误 Connection refused connect 请验证连接属性 并检查 SQL Server 的实例正在主机上运行 且
  • Kubernetes 基本概念

    Kubernetes 是什么 Kubernetes 是一个可移植 可扩展的开源平台 用于管理容器化的工作负载和服务 可促进声明式配 置和自动化 是谷歌保密了十几年的秘密武器Borg的开源版本 谷歌一直通过Borg系统管理着数量庞大 的应用程
  • 2023华为OD机试备考攻略 以及题库目录分值说明 考点说明

    刷题库 刷题库 刷题库 重要的事情说三遍 要刷有多种语言的实现的题库 一种语言看不懂可以换另一种语言 而且可以结合起来去重 类似下面这种的题库 华为OD机试备考攻略 以及题库目录分值说明 考点说明 blog csdn net banxia
  • copy of an AVPacket structure

    a copy of an AVPacket structure 参考 https stackoverflow com questions 12929330 create a copy of an avpacket structure ok
  • 回调函数的作用详解

    回调函数的作用 原文地址 回调函数的作用 加菲的日志 网易博客 一直不太理解回调函数的作用 下面是找到的一些关于回调函数的作用的解答 1 回调函数是一个很有用 也很重要的概念 当发生某种事件时 系统或其他函数将会自动调用你定义的一段函数 2
  • STM32的DMA输出DAC的正弦波与三角波 幅度与周期可调可调(原创篇);

    废话不多说 因为激光振镜驱动需要正弦波与三角波 为了省事 直接通过STM32F407实现DAC的DMA输出 省CPU资源 经过调试 在0 NkHZ之内都可以实现 目前采样点为500个 上数据吧 其中三角波自动生成500个数据 在初始化的时候
  • 自己的Anaconda管理多个虚拟环境,这样就可以在不同的环境下安装互不干扰的库

    项目场景 Anaconda可以安装多个虚拟解释器 每个解释器可以安装自己独有的库 从而每个解释器之间起到互不干扰的作用 这点Anaconda就非常强大了 查看Anaconda的解释环境 在电脑开始中选择Anaconda Prompt set
  • 搭建一个vue3+ts项目(超祥/必看)

    一 创建vite项目 1 在一个文件夹下通过cmd打开 输入命令 npm create vite latest 2 接着选择ts 3 创建好之后 结构目录如下 二 启动vite项目 1 安装依赖 启动项目前需要先 npm i 从上图可以发现
  • C++智能指针知识总结

    智能指针 智能指针是为了避免内存泄漏的技术 智能指针采用了RAII特性 利用对象生命周期来控制程序资源 在对象构造时获取资源 接着控制对资源的访问使之在对象的生命周期内始终保持有效 最后在对象析构的时候释放资源 借此 我们实际上把管理一份资
  • Python 四五事

    介绍 Python 相关工具 工作流程和测试框架 最后更新 2014 1 19 引言 接续着之前的文章 虽然隔得比较久 本文继续介绍以 Windows 平台为背景的 Python 开发相关的工具 希望能对你有所帮助 另外很多东西本文都是延续
  • html+css+javascript知识点总结

    一 html css 基础 1 1 Html 和 CSS 的关系 学习 web 前端开发基础技术需要掌握 HTML CSS JavaScript 语言 下面我们就来了解下这三门技术都是用来实现什么的 1 HTML 是网页内容的载体 内容就是
  • 14.12 修改职工信息

    14 12 修改职工信息 1 按照编号修改职工信息 先声明 修改职工 void mod Emp 再实现 就是把查到的职工删除 再在那个位置输入一个新职工 所以跟添加职工的代码很多地方一样 修改职工 void WorkerManager mo
  • Koordinator 异构资源/任务调度实践

    前言 Koordinator 是阿里云基于过去我们建设的统一调度系统中积累的技术和实践经验 对外开源了新一代的调度系统 Koordinator 支持 Kubernetes 上多种工作负载的混部调度 它的目标是提高工作负载的运行时效率和可靠性