通用图形处理器设计GPGPU基础与架构(四)
一、前言
本文将介绍GPGPU中线程束的调度方案、记分牌方案和线程块的分配与调度方案。
二、线程束调度
在计算机中有很多资源,既可以是虚拟的计算资源,如线程、进程或数据流,也可以是硬件资源,如处理器、网络连接或 ALU 单元。调度的目的是使得所有资源都处于忙碌状态,从而允许多个工作可以有效地同时共享资源,或达到指定的服务质量。
当 SM 中有众多线程束且处于就绪态(或活跃)时,需要调度器从其中挑选出一个。这个被选中的线程束会在接下来的执行周期中根据它的 PC 发射出一条新的指令来执行。从整个 SM 角度看,由于调度器每个周期都可以切换它所选择的线程束,不同线程束的不同指令可能会细粒度地交织在一起,而同一个线程束的指令则是顺序执行的,如下图所示:
2.1 基本的调度策略
GPGPU 线程束调度器的职责是从就绪的线程束中挑选一个或多个线程束发送给空闲的执行单元。这个过程看似简单,但由于连接了指令取指和执行两个关键步骤,调度器的选择会涉及整个GPGPU 执行过程的多方面,对 GPGPU 的性能有着重要的影响。
如何判断线程束是否“就绪”呢?在 GPGPU 架构中,NVIDIA 对发射停顿的原因有如下描述:
(1) Pipeline busy,指令运行所需的功能单元正忙;
(2) Texture 单元正忙;
(3) Constant 缓存缺失,一般说来会在第一次访问时缺失;
(4) Instruction Fetch,指令缓存缺失,一般只有第一次运行访问容易缺失;
(5) Memory Throttle,有大量存储访问操作尚未完成,为了不加剧性能损耗导致存储指令无法下发。这种原因造成的停顿可以通过合并存储器事务来缓解;
(6) Memory Dependency,由于请求资源不可用或满载导致 load/store 无法执行,可以通过存储访问对齐和改变访问模式来缓解;
(7) Synchronization,线程束在等待同步指令,如 CUDA 中的_syncthreads() 要求线程块中的所有线程都到达后才能统一继续执行下一条指令;
(8) Execution Dependency,输入依赖关系还未解决,即输入值未就绪。这与 CPU 中的数据相关是类似的。
只有消除了上述原因的线程束才可能被认为是可以发射的。
从指令缓存中读取到的指令一般会被存放在一个小的指令解码缓冲区中,指令缓冲区采用一个简单的表结构,表象数目与可编程多处理器所允许的最大线程ID数量相关。每个表项包含一个线程束的基本信息,如线程块ID,线程束ID和线程ID。
在众多就绪的线程束中,调度器根据不同的算法会有不同的选择策略。轮询(Round-Robin,RR)调度策略。如下图所示,它在调度过程中,对处于就绪状态的线程束0、1、3、4、5都赋予相同的优先级,并按照轮询的策略依次选择处于就绪状态的线程束指令进行调度,完成后再切换到下一个就绪线程束,如线程束0、1、3、4、5都执行完成指令0后再重复上述过程直到执行结束。与之相对应的另一种策略称为 GTO(Greedy-Then-Oldest)。 该策略允许一个线程束按照贪心策略一直执行到不能执行为止。下图 GTO 调度器首先选择了线程束0的前3条指令执行,直到无法继续执行指令,此时再切换到线程束1的前3条指令执行。GTO 调度与轮询调度可以认为是两种极端情况。
2.2 调度策略的优化
在 GPGPU 架构中,数据的访存延时仍然是影响性能的主要因素,而发掘数据的局部性则是改善访存延时最有效的手段之一。
由于 SIMT 架构的特点, 一般来讲内核函数中往往存在两种数据局部性:线程束内局部性(intra-warp locality)和线程束间局部性(inter-warp locality)。当数据被一个线程访问后,如果不久之后还会被同一线程束中的其他线程再次访问则称为线程束内局部性,而如果再次访问的是其他线程束中的线程则称为线程束间局部性。注意这里所谓的“再次访问”可能是这个数据本身,也可能是相邻地址的数据,因此是包含了时间和空间两种局部性而言的。
回顾轮询和 GTO 两种调度策略,其实两者就是发掘线程束内局部性和线程束间局部性的不同体现:轮询策略通过执行不同线程束的同一条指令,较好地获得了线程束间局部性;而GTO 策略则更多地考虑了线程束内的局部性。
使用轮询策略对16个线程束W0,W1,…,W15进行调度,每 个线程束中~均为运算指令,为访存指令。调度器依次调度各线程束的指令,直到16×(k-1) 个周期后,所有线程束先后进入访存指令,执行长延时操作,假设相邻线程束执行指令仅相差一个周期,此时也没有更多可供调度的线程束来隐藏访存延迟,这导致流水线陷入了一段较长时间的空闲。
GTO 策略则倾向于让一个线程束尽快执行。当遭遇了长延时操作时,其他线程束还可以有更多的指令用于掩藏延时,从而提供一定程度的改进。但GTO 策略可能会破坏线程间局部性,使得这些本来可以避免的访存缺失 反而需要更高的线程并行度来掩盖。
2.2.1 利用并行性掩藏长延时操作
(a)两级轮询调度
两级线程束调度(two-level warp scheduling)策略,它将所有线程束划分为固定大小的组(fetch group),组间基于优先级顺序的策略进行调度,但本质上还是轮询策略。16个线程束的例子,分为2组,每组包含8个线程束。第0组拥有较高优先级,第1组次之。调度器优先选取第0组调度,组内按照轮询策略依序执行各个线程束的指令、指令……直到组内8个线程束都执行完访存指令时,赋予第1组最高优先级并调度执行。此时还有8个线程束,每个线程束也有足够的指令(~) 可供调度,从而更好地掩藏第0组访存操作带来的长延时。
(b)线程块感知的两级轮询调度
线程块感知的两级线程束调度(Cooperative Thread Array aware two -level warp scheduling)利用线程块间的数据局部性,分组时将若干存在数据局部性的线程块分配到同一组中,程块内的线程束具有相等的优先级,线程束级同样按照轮询策略调度执行。
(c)结合数据预取的两级调度策略
按照两级轮询优先调度第0组配合简单预取策略,如上图(c)所示,在W0请求访问全局存储器时,对 W1 的预取 P1 也一样被发出,而 W1 真正被调度时已经在组0的线程束全部进入停顿之后,一部分预取时间已经被执行时间掩盖,从而能够提高预取质量。等到组0的数据和预取数据返回后,所有的线程束都可以计算。
2.2.2 利用局部性提高片上数据复用
利用数据的局部性对提升性能来讲也至关重要,当数据被加载到片上存储尤其是 L1 数据缓存后,如果能有效地重用这些数据提高缓存的命中率,既可以减少访存的延时,又可以减少重复的访存操作,相当于减少了长延时访存操作的次数。
一个进度分化的原因在于单一线程块内的线程束由于存储系统访问的不确定性,即便采用轮询调度,不同线程束的执行进度也可能存在较大差异。另外一个进度分化的重要原因就是在线程同步栅栏处或在分支线程重聚的位置,执行快的线程束先到达,等待执行慢的线程束。
关键性感知的线程束协调加速(Coordinated criticality-Aware Warp Acceleration,CAWA),线程束的 “关键性”(criticality)反映的就是线程束执行时间的长短,执行时间最长的线程束为关键线程束,给予关键线程束最高调度优先级,分配更多硬件和时间资源以满足执行需求。
基于 GTO 的关键性感知线程束调度策略(gCAWS),改进了调度选取线程束的机制,每次选择关键度最高的一个线程束执行,当有多个关键度相同的线程束时,选择生命周期最长的线程束执行,在执行阶段不断更新关键度的值。
三、记分牌
在通用处理器中,寄存器数据可能存在三种类型的相关:写后读、写后写 和读后写,都可能会导致冒险。
(1) 写后读(Read After Write,RAW),也称真数据相关(true dependence)。按照程序顺序,某个特定寄存器的写指令后面为该寄存器的读指令。若读指令先于写指令执行,则读指令只能访问到未被写指令更新的寄存器旧值,从而产生错误的执行结果。
(2) 写后写(Write After Write,WAW),也称名称相关(name dependence)。按照程序顺序,写指令1后为写指令2,并且都会更新同一个目的寄存器。若写指令2先于写指令1执行,则最后保留在目的寄存器中的是写指令1的结果,这与程序顺序执行的语义不符。
(3) 读后写(Write After Read,WAR),也称反相关(anti-dependence)。 按照程序顺序,对某个特定寄存器的读指令后面为该寄存器的写指令。若写指令先于读指令执行,则读指令将获取到更新后的寄存器值,产生错误的执行结果。
经典的记分牌技术通过标记指令状态、功能单元状态和寄存器结果状态,控制数据寄存器与功能单元之间的数据传送,实现了乱序流水线下指令相关性的检测和消除,保证了程序执行的正确性,同时提高了程序的执行性能。
3.1 GPGPU中的记分牌
为了提高 SIMT 运算单元的硬件效率,GPGPU 一般会采用顺序执行的方式,避免乱序流水线带来的指令管理开销。但 GPGPU 指令的执行仍然可能需要多个周期才能完成,而且不同指令存在不等长执行周期的情况。因此,为了让同一线程束的后续指令在发射时减少等待时间而尽早发射,仍然要保证前后指令之间不存在数据相关,从而提高指令的发射和执行效率。
记分牌的机制可以避免由数据相关导致的冒险情况发生。记分牌为每个线程束寄存器分配1个比特用于记录相应寄存器的写完成状态。如果正在执行的线程束指令将要写回的目标寄存器为Rx, 则在记分牌中将寄存器对应的标识置为1,表示该指令尚未写回完成。在此之前,如果同一线程束中的后续指令不存在数据相关,则可以尽早进入流水线执行。否则,指令不能发射。
记分牌设计方案虽然简单,但主要存在两方面的问题:
(1)若每个寄存器都分配1bit标识,记分牌将占用大量空间;
(2)所有待发射线程束指令在调度时需要一直查询记分牌,直到所依赖的指令执行完毕,更新寄存器标识位,才能发射后续指令,这会带来巨大开销。
3.2 记分牌设计优化
3.2.1 基于寄存器编号索引的记分牌设计
考虑到记分牌主要是对指令缓冲(I-Buffer) 中已解码的指令进行相关性检查才可能发射,因此可以将记分牌存储空间划分为与指令缓冲中指令数目相同的区域。
每个区域中包含若干条目,每个条目包含两个属性:寄存器RID(Register ID)和尺寸指示器。寄存器 RID 记录了该区域所对应的线程束目前正在执行的若干指令中,将要写回的目的寄存器编号。如果指令中将要写回的寄存器为一个序列,尺寸指示器则负责记录该寄存器序列的长度,而 RID 只需要记录这个序列中的第一个寄存器 RID。相关检查过程如下图(b)所示。
3.2.2 基于读写屏障的软件记分牌设计
软件记分牌设计:首先设计一定量的读写屏障,借助编译器分析,显式地将存在相关性的寄存器绑定到某个读写屏障上,在运行时,目的寄存器的写操作可以直接设定绑定的读写屏障,而源寄存器的读操作需要读取绑定的读写屏障来获知寄存器的写操作是否写完。这些信息由编译器提供,可以节省硬件开销,降低搜索代价,从而快速定位到绑定的读写屏障。
四、线程块分配与调度
线程块的分配和调度是 GPGPU 硬件多线程执行的前提。线程块的分配决定了哪些线程块会被安排到哪些 SM 上执行,而线程块的调度决定了已分配的线程块按照什么顺序执行。两者关系密切,对于 GPGPU 的性能有着直接的影响。
4.1 线程块的基本分配策略
在线程块分配方面,GPGPU 通常采用轮询作为基本策略。首先,线程块调度器将按照轮询方式为每个可编程多处理器分配至少一个线程块,若第一轮分配结束后可编程多处理器上仍有空闲未分配的资源(包括寄存器、共享存储器、线程块分配槽等),则进行第二轮分配,同理,若第二轮分配后仍有资源剩余,可以开始下一轮资源分配,直到所有可编程多处理器上的资源饱和为止。对于尚未分配的线程块,需要等待已分配的线程块执行完毕并将占有的资源释放后,才可以分配到可编程多处理器上执行。
假设一个 GPGPU 中有3个SM,分别为SM0 、SM1 和 SM2,每个 SM 允许最多同时执行2个线程块。一个内核函数声明了12个线程块 TB0~TB11。根据轮询的原则,TB0~TB2被分配到 SM0~SM2。由于每个 SM 可以同时执行2个线程块 ,TB3~TB5 也被分配到 SM0~SM2 中 。此时,SM 的硬件资源已经被完全占用,剩下的线程块暂时无法分配到 SM 中执行,必须等待有线程块执行完毕释放硬件资源,才能继续分配。一段时间后,SM2 中 TB5 率先执行完毕释放硬件资源,TB6 被分配到 SM2中 执行。
初始一轮的线程块分配顺序是轮询的,但第二轮的线程块分配完全是按照执行进度安排的。
4.2 线程块的基本调度策略
线程块的调度与线程束的调度策略有很高的关联性。两者对 GPGPU 的执行性能都有着重要的影响,只是调度的粒度有所不同。
假设有4个线程块 TB0~TB3 被分配到一个可编程多处理器上。图(a)中线程块和各自的线程束都按照 GTO 的方式调度,最终TB3线程没有被使用到,造成了资源的浪费。如果改变线程块的调度策略为轮询策略也会有另外的问题,假设 TB3 和 TB0 读取的数据都存放在同一缓存行中,就会导致 TB3 和 TB0 在数据缓存上存在竞争,产生缓存抖动问题,增加了缓存缺失率和访问开销。因此独立的调度策略设计并不能解决这个问题,需要与线程块分配策略协同优化。
4.3 线程块分配与调度的优化策略
1. 感知空间局部性的调度策略
(a)感知 L1缓存局部性的块级线程块调度
(b)感知 DRAM 板块的线程块协同调度
2. 感知时间局部性的抢占调度策略
3. 限制线程块数量的怠惰分配和调度策略
4. 利用线程块重聚类感知局部性的软件调度策略
相关文章:
通用图形处理器设计GPGPU基础与架构(四)
一、前言 本文将介绍GPGPU中线程束的调度方案、记分牌方案和线程块的分配与调度方案。 二、线程束调度 在计算机中有很多资源,既可以是虚拟的计算资源,如线程、进程或数据流,也可以是硬件资源,如处理器、网络连接或 ALU 单元。调…...
会Excel就会sql?
如果你熟悉Excel,理解SQL(结构化查询语言,Structured Query Language)会相对容易,因为它们在某些功能上有着相似之处。SQL主要用于管理和操作数据库中的数据,而Excel则是电子表格软件,用于数据的组织、分析和可视化。下面我会用Excel的视角来帮你理解SQL的基本概念。 数…...
MyBatis-Plus的几种常见用法
MyBatis-Plus 提供了丰富的高级用法,可以简化开发,提高效率。以下是一些常见的可能会被忽略的用法示例。 1. 乐观锁 乐观锁用于避免在并发环境下数据更新冲突。MyBatis-Plus 通过注解和版本字段实现乐观锁。 示例: 在实体类中添加版本字段…...
【LeetCode】day15:110 - 平衡二叉树, 257 - 二叉树的所有路径, 404 - 左叶子之和, 222 - 完全二叉树的节点个数
LeetCode 代码随想录跟练 Day15 110.平衡二叉树257.二叉树的所有路径404.左叶子之和222.完全二叉树的节点个数 110.平衡二叉树 题目描述: 给定一个二叉树,判断它是否是 平衡二叉树 平衡二叉树的定义是,对于树中的每个节点,其左右…...
【网络安全的神秘世界】Error:Archives directory /var/cache/apt/archives/partial is missing.
🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 ✨问题描述 在kali中想要安装beef-xss软件包时,发生如下报错: Error: Archives directory /var/cac…...
网络编程中的TCP和UDP
什么是TCP协议 TCP( Transmission control protocol )即传输控制协议,是一种面向连接、可靠的数据传输协议,它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接 :数据传输之前客户端和服务器端必须建立连…...
基于python的时空地理加权回归(GTWR)模型
一、时空地理加权回归(GTWR)模型 时空地理加权回归(GTWR)模型是由美国科罗拉多州立大学的Andy Liaw、Stanley A. Fiel和Michael E. Bock于2008年提出的一种高级空间统计分析方法。它是在传统地理加权回归(GWR…...
什么是单例模式,有哪些应用?
目录 一、定义 二、应用场景 三、6种实现方式 1、懒汉式,线程不安全。 2、懒汉式,线程安全 3、双检锁/双重校验锁(DCL,即 double-checked locking) 4、静态内部类方式-------只适用于静态域 5、饿汉式 6、枚举…...
adb命令操作手机各种开关
打开iqoo手机热点设置 adb shell am start -n com.android.settings/com.android.settings.Settings$\VivoTetherSettingsActivity蓝牙模块 检查蓝牙状态的ADB命令 检查蓝牙开关状态 adb shell settings get global bluetooth_on开启和关闭蓝牙 使用Intent操作蓝牙…...
【分布式存储系统HDFS】架构和使用
分布式存储系统HDFS:架构和使用 目录 引言HDFS简介HDFS的架构 NameNodeDataNodeSecondary NameNode HDFS的工作原理 数据读写流程数据冗余与恢复 HDFS的安装和配置 环境准备HDFS安装步骤HDFS配置文件启动HDFS HDFS的使用 基本命令HDFS Shell操作Java API操作 HDFS…...
Linux 实验一Linux系统安装
一、实验日期与地址 1、实验日期:2024年 2 月28 日 2、实验地址:S1-504 二、实验目的 1、掌握VMware Workstation建立虚拟机 2、掌握虚拟机环境下安装Centos 7 三、实验环境 VMware Workstation、Centos 7 四、实验内容 1、安装VMware Workstat…...
【人工智能】深度剖析AI伦理:强化隐私防线,推动算法公平性的核心议题
文章目录 🍊1 人工智能兴起背后的伦理及道德风险1.1 算法偏见与歧视1.2 数据隐私侵权1.3 透明度受限1.4 决策失衡1.5 AI生成内容的危险性 🍊2 建构AIGC伦理观:实现人机共创的永续提升2.1 技术手段与伦理预防2.2 即时警告与紧急关停措施2.3 法…...
如何解决微服务下引起的 分布式事务问题
一、什么是分布式事务? 虽然叫分布式事务,但不是一定是分布式部署的服务之间才会产生分布式事务。不是在同一个服务或同一个数据库架构下,产生的事务,也就是分布式事务。 跨数据源的分布式事务 跨服务的分布式事务 二、解决方…...
牛客周赛50轮+cf955+abc363
D-小红的因式分解_牛客周赛 Round 50 (nowcoder.com) 思路: 巨蠢的题目,ax^2bxca1*a2*x^2(b1*a2b2*a1)xb1*b2,即: aa1*a2,ba1*b2a2*b1,cb1*b2 数据范围很小,直接暴力枚举吧(注意条件) 代码…...
【MySQL】:对库和表的基本操作方法
数据库使用的介绍 什么是SQL 学习数据库的使用——>基于 SQL编程语言 来对数据库进行操作 重点表述的是“需求”,期望得到什么结果。(至于结果是如何得到的,并不关键,都是数据库服务器在背后做好了) 重点表述的是…...
Library not found for -lstdc++.6.0.9
解决方案一 由于项目已经很多年了,前段时间更新了Xcode发现编译报错lstdc这个库很早以前就被舍弃了,但是一个项目的维护都随着解决bug堆砌出来的,这也导致了我们的项目走上了这条路。 比如 Library not found for -lstdc.6.0.9 报的错&#x…...
防火墙之双机热备篇
为什么要在防火墙上配置双机热备技术呢? 相信大家都知道,为了提高可靠性,避免单点故障 肯定有聪明的小伙伴会想到那为什么不直接多配置两台防火墙,然后再将他们进行线路冗余,不就完成备份了吗? 答案是不…...
终端里面ifconfig命令无法运行
在 Ubuntu 以及基于 Debian 的系统中,ifconfig 命令可能不会默认安装,因为自 Ubuntu 17.10 版本开始,系统默认使用 ip 命令作为网络配置的主要工具,而 ifconfig 命令则来自 net-tools 包,该包不再作为标准工具被包含在…...
掌握Python中的文件序列化:Json和Pickle模块解析
Python 文件操作与管理:Open函数、Json与Pickle、Os模块 在Python中,文件是一个重要的数据处理对象。无论是读取数据、保存数据还是进行数据处理,文件操作都是Python编程中不可或缺的一部分。本文将详细介绍Python中文件操作的几种常用方法&…...
WordPress 6.6 “Dorsey多尔西”发布
WordPress 6.6 “Dorsey多尔西”已经发布,它以传奇的美国大乐队领袖 Tommy Dorsey 名字命名。Dorsey 以其音调流畅的长号和作品而闻名,他的音乐以其情感深度和充满活力的能量吸引了观众。 当您探索 WordPress 6.6 的新功能和增强功能时,让您的…...
核函数支持向量机(Kernel SVM)
核函数支持向量机(Kernel SVM)是一种非常强大的分类器,能够在非线性数据集上实现良好的分类效果。以下是关于核函数支持向量机的详细数学模型理论知识推导、实施步骤与参数解读,以及两个多维数据实例(一个未优化模型&a…...
二分查找(折半查找)
这次不排序了,对排好序的数组做个查找吧 介绍 二分查找排序英文名为BinarySort,是一种效率较高的查找方法要求线性表必须采用顺序存储结构 基本思路 通过不断地将搜索范围缩小一半来找到目标元素: 1、假定数组为arr,需要查找的…...
arcgis紧凑型切片缓存(解决大范围切片,文件数量大的问题)
ArcGIS 切片缓存的紧凑型存储格式是一种优化的存储方式,用于提高切片缓存的存储效率和访问速度。紧凑型存储格式将多个切片文件合并为一个单一的 .bundle 文件,从而减少文件系统的开销和切片的加载时间。这类格式已经应用很久了,我记得2013我…...
ESP32CAM人工智能教学15
ESP32CAM人工智能教学15 Flask服务器TCP连接 小智利用Flask在计算机中创建一个虚拟的网页服务器服务器,让ESP32Cam通过WiFi连接,把摄像头拍摄到的图片发送到电脑中,并在电脑中保存成图片文件。 Flask是用Python编写的网页服务程序WebServer。…...
Pandas 33个冷知识 0721
Pandas 33个冷知识 从Excel读取数据: 使用 pd.read_excel(file.xlsx) 来读取Excel文件。 写入Excel: 使用 df.to_excel(file.xlsx, indexFalse) 将DataFrame写入Excel文件。 创建日期索引: 使用 df.set_index(pd.to_datetime(df[date])) 创建日期索引。 向后填充缺失值: 使用…...
C++ map和set的使用
目录 0.前言 1.关联式容器 2.键值对 3.树形结构的关联式容器 3.1树形结构的特点 3.2树形结构在关联式容器中的应用 4.set 4.1概念与性质 4.2使用 5.multiset 5.1概念与性质 5.2使用 6.map 6.1概念与性质 6.2使用 7.multimap 7.1概念与性质 7.2使用 8.小结 &a…...
yarn的安装和配置以及更新总结,npm的对照使用差异
1. Yarn简介 Yarn 是一个由 Facebook 开发的现代 JavaScript 包管理器,旨在提供更快、更安全、更可靠的包管理体验。 1.1 什么是Yarn Yarn 是一个快速、可靠和安全的 JavaScript 包管理器,它通过并行化操作和智能缓存机制,显著提升了依赖安…...
【Git命令】git rebase之合并提交记录
使用场景 在本地提交了两个commit,但是发现根本没有没必要分为两次,需要想办法把两次提交合并成一个提交;这个时候可以使用如下命令启动交互式变基会话: git rebase -i HEAD~N这里 N 是你想要重新调整的最近的提交数。 如下在本地…...
为什么品牌需要做 IP 形象?
品牌做IP形象的原因有多方面,这些原因共同构成了IP形象在品牌建设中的重要性和价值,主要原因有以下几个方面: 增强品牌识别度与记忆点: IP形象作为品牌的视觉符号,具有独特性和辨识性,能够在消费者心中留…...
Kubernetes 1.24 版弃用 Dockershim 后如何迁移到 containerd 和 CRI-O
在本系列的上一篇文章中,我们讨论了什么是 CRI 和 OCI,Docker、containerd、CRI-O 之间的区别以及它们的架构等。最近,我们得知 Docker 即将从 kubernetes 中弃用!(查看 kubernetes 官方的这篇文章)那么让我…...
山东网站app制作/北京朝阳区优化
clickHouse的简单介绍,详细介绍请查看官网或者百度1)clickhouse非hadoop体系2)使用sql语句,对于熟悉关系数据的人员入门相对简单3)clickhouse最好用来读,不要用来变更,写用批量的方式4)各种日志数据我们可以用flume同步到clickhou…...
建设阿里巴巴网站首页/怎么做网站关键词优化
Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。 Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。 接下来我们来看一段代码…...
高级经济师/seo推广知识
Daniel2cscanf我不知道为什么,当我运行它时,它会跳过"书中有多少页" scanf并直接进入第二个循环"谁是作者".我确定这与空白有关,但我认为我用getcharfor循环的底部来解释这个问题.标题:struct bookInfo{char title[40];char author[25];float price;int pa…...
linux wordpress 下载/湖南长沙最新疫情
1.JS基本语法: 1.js引入方式 js是脚本语言,可以在浏览器中执行。js文件是以.js为结尾的,引入html文件中时使用script标签,这时script需要添加一个属性src,src中写js文件的路径;但是js还可以直接写在html当中…...
网站备案到公司名称/手游推广赚佣金的平台
重点内容:创建组件的方法,组件的props属性、state属性的用法和特点,父子组件传值,兄弟组件传值; 开头 其实组件感觉很绕,但是也就几个点,理清思路,学起来就比较容易,所…...
做区块链在哪个网站/培训报名
在实际开发中,项目经理会一直强调一句话,永远不要相信客户端的数据(前端可以不用验证,但是后端必须验证)。大家同意这样的说法吧。。新端验证毋庸质疑JS验证,提高用户体验我们不得不添加一些与后端一致的验证逻辑,同样…...