淘宝做网站费用/网站优化公司哪家效果好
参考:
Go 汇编函数 - Go 语言高级编程
Go 嵌套汇编 - 掘金 (juejin.cn)
前言:
Golang 适用 Go-Runtime(Go 运行时,嵌入在被编译的PE可执行文件之中)来管理调度协同程式的运行。
Go 语言没有多线程(MT)的概念,在 Go 语言之中,每个 Go 协程就类似开辟了一个新的线程,效率上,肯定是比分配线程好的。
但也仅限于分配协程,及单个进程可以跑几万个乃至几十万个协同程序,这是线程无法比拟的,因为在操作系统之中,最小执行单元的单位就是线程了,但是线程相对协同程序来说,过重,无论是内存还是CPU。
但不意味着 Go 协程执行的效率比线程要好,别太自信与盲目,协程是比不了线程代码CPU执行效率的。
上面也提到了,只是可以同时开辟几万个乃至几十万个协程,并且启动协程速度比线程快非常多,这是它的优势,但是缺点也很明显,在物理线程上执行 Go 协同程式的代码效率不高。
目前世界上最快的协同程序切换,应该是 C/C++ 之中的:
State Threads Library (sourceforge.net)
boost::context
两个库各有千秋,但相对来说 boost 更好用一些,在这里需要提醒大家一点,应用程序之中运行协同程序,它是依托于进程之中的物理线程上执行的。
来到正题,我们先来探讨 Golang 到底是 “Stackless” 无栈轻量协程,还是 “Stackful” 有栈重量协程呢?
那么就有必要分析清楚,有栈协程跟无栈协程之间到底有什么区别。
首先:
1、有栈协程
1.1、栈协程是一种基于线程或进程的协程实现方式。
1.2、栈协程拥有自己的执行栈,可以独立地管理栈帧、局部变量和函数调用。
1.3、栈协程的切换需要保存和恢复整个执行上下文,包括栈指针、寄存器等。
1.4、由于栈协程具有独立的执行栈,因此它们可以支持递归调用和深度嵌套。
1.5、由于栈协程需要额外的资源来维护栈,因此在创建和销毁方面可能会有一些开销。
2、无栈协程
2.1、无栈协同是一种基于用户空间的协程实现方式。
2.2、无栈协同没有独立的执行栈,它们共享相同的调用栈。【重点】
2.3、无栈协同使用状态机来管理协程的执行,并通过保存和恢复状态来实现协程的切换。
2.4、由于无栈协同共享调用栈,因此它们不能支持递归调用和深度嵌套。
2.5、无栈协同通常比栈协程更轻量级,创建和销毁开销较小。
似乎从上述定义的概念来说,Golang 是有栈协议?但真的是这样吗?显然不是的,首先真正意义上的有栈协程,是无法被运行时代管的。
有栈协程存在以下几个限制:
1、如果开发人员切换协程处理不当的情况下,会导致协程栈内存泄漏问题。
2、如果开发人员在多个线程之中执行
3、有栈协程无法动态扩展计算栈空间,所以有栈协程需要在分配时,明确指定栈空间大小。
一个协同程序可以在多个线程上按保证顺序性(时序)进行处理,无论是有栈协同程序、或者是无栈协同程序,均可以。
Go 协同程序是属于 “Stackless” 无栈协程的类型,但 Go 为了实现协同程序能像 Stackful 有栈协程一样,拥有属于自己的外挂栈空间,并且支持动态栈空间扩容。
但要注意一点:
1、Go 协程可能在不同的线程上面被执行,虽然 Go 语言运行时保证了,单一协同程序执行的时序性,但开发人员需要在其中注意协同程序之间的同步问题,类似多线程并发编程。
2、若要实现同步锁的情况,人们需要考虑多线程问题,否则这可能造成很严重的后果,即 Go 运行时附着的工作线程被阻塞,同时最好的实现方式伪同步锁,如利用管道来实现类似效果。
相对传统的 TTASLock/CAS自选锁实现,可能不太适合Go 这种结构的程序,这是因为:Go 协同程序在没有执行异步的情况下是不会让出线程CPU的,你可以理解为,你需要执行类似文件IO、网络IO、或者调用 Go 运行时库之中的同步库,例如:sync.Mutex 产生了阻塞行为
鉴于 Go 运行时是多线程执行,在不阻塞 Go 运行时最大工作线程的情况下,其它协程,仍旧是可以正常就绪的工作的,这取决于运行时调度。
所以严格意义上来说,Go 协程属于 “Stackless” + “Stackful” 的变种协程,它属于 “Stackless” 无栈协同程序的一种,但 Go 编译器实现对其用户代码进行展开,并分配一个 “Go 外挂计算栈内存空间单元”,而非真正意义上的函数栈,如同C#、C++、C#、ASM、IL函数的调用堆栈。
有栈协程无法放大执行堆栈的根本原因是寄存器,EIP、RIP,及地址链之间存在上下依赖问题等等,Go 并非是真的有栈协程,自然不会存在这个问题,它本来就是由编译器支持的黑魔法,实现的协同程序(“重点:最终会被展开编译为状态机切换的”),但这类编译器不能编译过度复杂协同应用程序,虽然我个人是相信 Google 的技术水平的,但并不代表,不对 Stackless 协程先天存在的对于编译器的复杂性,感到一丝忧虑,这个世界上不存在完美的技术,这类编译器完全内部实现的纯纯黑盒,对开发人员来说不太容易掌控到更多的细节。
Go 通过外挂计算栈空间的解决方案,在该 Go 栈空间内不保存任何寄存器之类的值,仅存储调用函数栈帧的元RID、参数、变量等(值或引用),所以在栈空间不足时,进行扩大外挂栈时。
即:分配新的栈空间内存,并把原栈内存复制过来,在释放原栈内存空间的内存,并把新的栈内存首地址(指针)挂载到当前 Go 协同程序的栈顶指针、栈底指针。
在复制并放大 Go 协程栈内存空间的时候,会导致该协同被同步阻塞,恢复取决于这个步骤在何时完成。
Go 栈空间虽然不会保存寄存器的值,但并不意味着 Go 程序不会适用目标平台汇编指令集
下述是一个很简单的 Go 加法函数,返回参数 x+y 的值:
package mainfunc Add(x int, y int) int {return x + y
}func main() {}
那么 Go 编译器会输出以下的汇编指令
TEXT main.Add(SB), NOSPLIT|NOFRAME|ABIInternal, $0-16FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $5, main.Add.arginfo1(SB)FUNCDATA $6, main.Add.argliveinfo(SB)PCDATA $3, $1ADDQ BX, AXRETTEXT main.main(SB), NOSPLIT|NOFRAME|ABIInternal, $0-0FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)RET
从上述的代码中,我们可以清晰的看到,出现了并非X86/X64汇编语法的,FUNCDATA 、PCDATA 两个指令。
它们是 GO 汇编之中的伪指令,注意它是伪指令,意思就是说这东西不能用,除了GO的编译器能理解它之外,其它的汇编器,无论 GCC、VC++ 都是不认识这个东西。
人们可以理解,Go 存在两个编译过程,一个前端编译器,一个后端编译器,前端编译器就是把我们写的 .go 源文件的程序代码编译为 Go 后端编译器认识的 Go 汇编指令集代码。
这的确很类似于 JAVA/JVM 编译的字节码、C# 编译器的 MSIL 中间指令代码,但又存在明显的区别,人们可以显著的参考下述在ARM平台输出的 Go 汇编代码
TEXT main.Add(SB), LEAF|NOFRAME|ABIInternal, $-4-12FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $5, main.Add.arginfo1(SB)MOVW main.x(FP), R0MOVW main.y+4(FP), R1ADD R1, R0, R0MOVW R0, main.~r0+8(FP)JMP (R14)TEXT main.main(SB), LEAF|NOFRAME|ABIInternal, $-4-0FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)JMP (R14)
人们可以明显的看到,除了几个伪指令是相同他的,但是内部实现所使用的指令发生了变化,这是因为,Go 每个平台编译器生成的 Go 汇编代码会根据CPU指令集平台的不同而不同,这是因为 Go 虽然编译的是只能给 Go 后端编译器看的汇编代码。
但不意味着它会完全按照先编译为字节码、中间代码的形式,Go 前端编译器输出的 Go 汇编,在编译的过程中,就已经按照目的平台的指令集进行了一部分的翻译(不完全是真汇编,但汇编已很接近了。)
剩下那部分伪指令是让 Go 汇编器,在构建目的程序时,所需处理的东西,就是GC、外挂栈空间内存上面的参数、局部变量读取这些实现,最后生成的目的汇编代码,才是用来编译为目的PE、ELF可执行文件的。
OK:这里简单的描述下上面X86汇编的意义,ARM我不怎么看得懂,所以不在此处献丑了
第一句 Go 汇编指令:
TEXT main.Add(SB), NOSPLIT|NOFRAME|ABIInternal, $0-16
1、TEXT: 这是一个伪指令,用于指示下面的代码是函数代码(类似于其他汇编语言中的函数标签)。
2、main.Add(SB): main.Add 是函数的名称,SB 表示 Static Base(静态基址),它是一个汇编符号,指示函数相对于全局数据区的偏移量。
3、NOSPLIT|NOFRAME|ABIInternal: 这是函数的属性标志。NOSPLIT 指示编译器不应在函数内插入栈分裂代码,NOFRAME 指示编译器不应创建函数堆栈帧,ABIInternal 表示该函数的调用约定为 Go 内部使用。
4、$0-16: 这是函数的栈帧大小指令。$0 表示该函数不会在栈上分配任何局部变量的空间,-16 表示函数会从参数中读取16字节的数据。
注意:这个栈空间指的是 Go 程序外挂的栈哈,不是进程线程的栈空间。(或为虚拟栈空间)
第二句 Go 汇编指令:
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
1、这是一个 FUNCDATA 伪指令,用于插入与垃圾回收(garbage collection)相关的元数据。
2、$0 表示这段元数据的索引值为 0(参数位:0 = X)
3、gclocals·g2BeySu+wFnoycgXfElmcg==(SB) 是一个符号名,它引用了一个包含局部变量和参数信息的数据结构。
第三句 Go 汇编指令:
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
跟第二句没区别,元数据索引值为 1(参数位:1 = Y)
第四句 Go 汇编指令:
FUNCDATA $5, main.Add.arginfo1(SB)
main.Add.arginfo1(SB) 是获取 “描述函数参数类型和数量的数据结构的引用地址”。
Go 语言没有显示的函数签名声明,所以编译器需要这个函数的参数信息,以便于可以正确的传递参数值给该函数。
第五句 Go 汇编指令:
FUNCDATA $6, main.Add.argliveinfo(SB)
main.Add.argliveinfo(SB) 是获取 “描述函数参数活跃性的数据结构的引用地址”
参数的活跃性指的是在函数执行期间哪些参数被使用了。这些信息对于优化代码的执行效率非常重要,GO GC在用。
第六句 Go 汇编指令
PCDATA $3, $1
把 $1 的值复制到 $3,AT&T汇编风格是:
操作数 原操作数, 目标操作数
加法实现 GO 汇编指令
ADDQ BX, AX
RET
1、AX 和 BX 寄存器用于存储 x 和 y 的值。
2、之后,通过 ADDQ BX, AX 指令将 y 的值加到 x 上,并将结果保存在 AX 寄存器中。
3、最后,使用 RET 指令将结果返回。
总结:
1、Golang 协程不会保存CPU寄存器的值。
2、Golang 协程属于 Stackless 协程的一种变种。
3、Golang 通过为外挂计算栈内存空间,来实现类似有栈协程的效果。
4、Golang 两个协程可能在不同的物理线程上面工作,所以公用数据访问时,须注意同步问题。
5、Golang 协程在处理异步操作的时,让出了当前协程占用的线程CPU,协程处于WAIT状态时, 当前协程依赖的外部数据,可能在外部发生了改变或者释放。
所以,该协程被唤醒之后(resume\awake)理应检查当前依赖数据的状态,如:在该协程处于 Yield 等待状态之中时,其它协程调用了 Dispose 函数,释放了 “它(公用数据)” 持有的全部被托管及非托管资源。
6、Golang 也会适用寄存器优化,但这有一些前提,就是简单的算术运算,可以被编译为寄存器优化的代码,这不冲突,只是最终会把值存储到 “Go” 为每个协程分配的外挂栈内存空间上面。
就像在 MSIL 之中,人们执行 stloc.s、ldloc.s、ldarg.s、starg.s 这些指令集一样,只不过它不像微软的 .NET CLR 会把这些代码编译为近似 C/C++ 编译器输出的目标平台汇编代码,当然不管怎么做,这类由GC系统标记的语言,都会在最终编译输出的汇编代码之中插入引用技术管理的实现,区别是在什么地方插入,当然这的看GC系统是怎么设计的,比如链式遍历的GC,就不需要在每个函数引用资源的地方去做 AddRef、到结尾做 ReleaseRef 这样的行为,但缺点就是GC在处理终结的时候,CPU开销比较大。
7、Golang 之中托管资源是通过RID间接引用的,即托管资源并非是直接使用指针,这是因为资源或会被GC压缩或移动碎片整理,当然这个时候会导致阻塞问题,即:GC Pinned 问题。
相关文章:

关于 Go 协同程序(Coroutines 协程)、Go 汇编及一些注意事项。
参考: Go 汇编函数 - Go 语言高级编程 Go 嵌套汇编 - 掘金 (juejin.cn) 前言: Golang 适用 Go-Runtime(Go 运行时,嵌入在被编译的PE可执行文件之中)来管理调度协同程式的运行。 Go 语言没有多线程(MT&a…...

深入剖析BaseMapperPlus扩展接口及其在MyBatis-Plus中的实践价值
前言 BaseMapperPlus并非MyBatis-Plus(MP)官方提供的标准接口,而是社区开发者基于MP的BaseMapper接口进行二次封装和增强后创建的一个自定义接口。这个概念可能因不同项目或个人实践而有所差异,但其核心思想是为了解决特定场景下…...

Linux之安装配置VCentOS7+换源
目录 一、安装 二、配置 三、安装工具XSHELL 3.1 使用XSHELL连接Linux 四、换源 前言 首先需要安装VMware虚拟机,在虚拟机里进行安装Linux 简介 Linux,一般指GNU/Linux(单独的Linux内核并不可直接使用,一般搭配GNU套件&#…...

[极客大挑战 2019]LoveSQL1
万能密码测试,发现注入点 注意这里#要使用url编码才能正常注入 测试列数,得三列 查看table,一个是geekuser另一个是l0ve1ysq1 查看column,有id,username,password,全部打印出来,…...

网络安全的介绍
1.什么是网络安全 网络安全是一门关注保护计算机系统、网络基础设施和数据免受未经授权访问、破坏或窃取的学科。随着数字化时代的发展,网络安全变得尤为重要,因为大量的个人信息、商业机密和政府数据都储存在电子设备和云端系统中。以下是网络安全的概…...

django邮件通知功能-
需求: 1:下单人员下订单时需要向组长和投流手发送邮件通知 2:为何使用邮件通知功能?因为没钱去开通短信通知功能 设计 1:给用户信息表添加2个字段 第一个字段为:是否开通邮件通知的布尔值 第二个字段为: 用…...

C++ 类定义
C 类定义 定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。 定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么࿰…...

IntelliJ IDE 插件开发 | (五)VFS 与编辑器
系列文章 IntelliJ IDE 插件开发 |(一)快速入门IntelliJ IDE 插件开发 |(二)UI 界面与数据持久化IntelliJ IDE 插件开发 |(三)消息通知与事件监听IntelliJ IDE 插件开发 |(四)来查收…...

金融OCR领域实习日志(一)
一、OCR基础 任务要求: 工作原理 OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相)检查纸上打印的字符,经过检测暗、亮的模式肯定其形状,而后用…...

CC++编译和链接介绍
介绍 C语言的编译和链接是将源代码转换为可执行文件的两个关键步骤。以下是详细的流程: 编译过程(Compilation) 预处理(Preprocessing): 编译器首先对源代码进行预处理,这个阶段处理#include包…...

Element-UI中的el-upload插件上传文件action和headers参数
官网给的例子action都是绝对地址,我现在需要上传到自己后台的地址,只有一个路由地址/task/upload 根据 config/index.js配置,那么action要写成/api/task/upload,另外也可以传入函数来返回地址:action"uploadUrl()"。 …...

在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
目录 博客前言 一.创建springboot项目 新建项目 选择创建类型编辑 测试 二.集成达梦数据库 添加达梦数据库部分依赖 添加数据库驱动包 配置数据库连接信息 编写测试代码 验证连接是否成功 博客前言 随着数字化时代的到来,数据库在应用程序中的地位越来…...

docker相关
下载Ubuntu18.04文件64位(32位安装不了MySQL) https://old-releases.ubuntu.com/releases/18.04.4/?_ga2.44113060.1243545826.1617173008-2055924693.1608557140 Linux ubuntu16.04打开控制台:到桌面,可以按快捷键ctrlaltt 查…...

生产力工具|卸载并重装Anaconda3
一、Anaconda3卸载 (一)官方方案一(Uninstall-Anaconda3-不能删除配置文件) 官方推荐的方案是两种,一种是直接在Anaconda的安装路径下,双击: (可以在搜索栏或者使用everything里面搜…...

大模型学习与实践笔记(十二)
使用RAG方式,构建opencv专业资料构建专业知识库,并搭建专业问答助手,并将模型部署到openxlab 平台 代码仓库:https://github.com/AllYoung/LLM4opencv 1:创建代码仓库 在 GitHub 中创建存放应用代码的仓库ÿ…...

Vulnhub靶机:FunBox 5
一、介绍 运行环境:Virtualbox 攻击机:kali(10.0.2.15) 靶机:FunBox 5(10.0.2.30) 目标:获取靶机root权限和flag 靶机下载地址:https://www.vulnhub.com/entry/funb…...

性能优化(CPU优化技术)-NEON指令介绍
「发表于知乎专栏《移动端算法优化》」 本文主要介绍了 NEON 指令相关的知识,首先通过讲解 arm 指令集的分类,NEON寄存器的类型,树立基本概念。然后进一步梳理了 NEON 汇编以及 intrinsics 指令的格式。最后结合指令的分类,使用例…...

【极数系列】Flink环境搭建(02)
【极数系列】Flink环境搭建(02) 引言 1.linux 直接在linux上使用jdk11flink1.18.0版本部署 2.docker 使用容器部署比较方便,一键启动停止,方便参数调整 3.windows 搭建Flink 1.18.0版本需要使用Cygwin或wsl工具模拟unix环境…...

仓储管理系统——软件工程报告(需求分析)②
需求分析 一、系统概况 仓库管理系统是一种基于互联网对实际仓库的管理平台,旨在提供一个方便、快捷、安全的存取货物和查询商品信息平台。该系统通过在线用户登录查询,可以线上操作线下具体出/入库操作、查询仓库商品信息、提高仓库运作效率ÿ…...

立创EDA学习:PCB布局
参考内容 【PCB布线教程 | 嘉立创EDA专业版入门教程(11)】 https://www.bilibili.com/video/BV1mW4y1Z7kb/?share_sourcecopy_web&vd_sourcebe33b1553b08cc7b94afdd6c8a50dc5a 单路布线 遵循顺序 先近后远,先易后难 可以拖动让拐角缩小…...

tomcat与Apache---一起学习吧之服务器
Apache和Tomcat都是Web服务器,但它们有一些重要的区别。 Apache服务器是普通服务器,本身只支持HTML即普通网页。不过可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资…...

Vue3的优势
Vue3和Vue2之间存在以下主要区别: 1. 性能优化:Vue3在内部进行了重写和优化,采用了新的响应式系统(Proxy),相较于Vue2中的Object.defineProperty,更具性能优势。Vue3还对编译和渲染进行了优化&…...

鸿蒙开发案例002
1、目标需求 界面有增大字体按钮,每次点击增大字体按钮,“Hello ArkTS”都会变大 2、源代码 Entry Component struct Page {textValue: string Hello ArkTSState textSize: number 50myClick():void{this.textSize 4}build() {Row() {Column() {//…...

Git学习笔记(第9章):国内代码托管中心Gitee
目录 9.1 简介 9.1.1 Gitee概述 9.1.2 Gitee帐号注册和登录 9.2 VSCode登录Gitee账号 9.3 创建远程库 9.4 本地库推送到远程库(push) 9.5 导入GitHub项目 9.6 删除远程库 9.1 简介 9.1.1 Gitee概述 众所周知,GitHub服务器在国外,使用GitHub作为…...

使用k8s 配置 RollingUpdate 滚动更新实现应用的灰度发布
方案实现方式: RollingUpdate 滚动更新机制 当某个服务需要升级时,传统的做法是,先将要更新的服务下线,业务停止后再更新版本和配置,然后重新启动服务。 如果业务集群规模较大时,这个工作就变成了一个挑战…...

MATLAB知识点:mode :计算众数
讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。 MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自第3章 3.4.1节 mode :计算众数 众数是指一…...

【JavaWeb】MVC架构模式
文章目录 MVC是什么?一、M :Model 模型层二、V:View 视图层三、C:Controller 控制层四、非前后端分离MVC五、前后端分离MVC总结 MVC是什么? MVC(Model View Controller)是软件工程中的一种**软件…...

【Unity学习笔记】创建人物控制器
人物左右移动 1 导入模型,如果没有模型,则在 窗口-资产商店-free sample 找到人物模型 2 在 窗口-包管理中 导入自己的模型 3 在自己的资产文件夹中找到Prefabs Base HighQuality MaleFree1模型,导入到场景中 4 Assets中创建C#项目 写入如下…...

HCIP:不同VLAN下实现网络互相通信
配置pc1 配置pc2 配置pc3 将sw1划分到vlan3 将sw3划分到vlan3 在sw1上进行缺省 将sw1上(g0/0/1)的untagged改成 1 3 则在pc1上ping pc2可通 在sw1上进行缺省 在sw3上(e0/0/1)打标记 则在pc1上ping pc3可通(实现互通&am…...

07 队列
目录 1.队列 2.实现 3.OJ题 1. 队列 只允许在一段进行插入数据操作,在另一端进行数据删除操作的特殊线性表,队列具有先进先出FIFO(First In Firtst Out),插入操作的叫队尾,删除操作的叫队头 2. 实现 队列…...