当前位置: 首页 > news >正文

网站怎么做外链接怎么建设一个自己的网站

网站怎么做外链接,怎么建设一个自己的网站,wordpress 4.7下载,深圳网站设计服参考#xff1a; Go 汇编函数 - Go 语言高级编程 Go 嵌套汇编 - 掘金 (juejin.cn) 前言#xff1a; Golang 适用 Go-Runtime#xff08;Go 运行时#xff0c;嵌入在被编译的PE可执行文件之中#xff09;来管理调度协同程式的运行。 Go 语言没有多线程#xff08;MT  Go 汇编函数 - Go 语言高级编程 Go 嵌套汇编 - 掘金 (juejin.cn) 前言 Golang 适用 Go-RuntimeGo 运行时嵌入在被编译的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 加法函数返回参数 xy 的值 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·g2BeySuwFnoycgXfElmcg(SB)FUNCDATA $1, gclocals·g2BeySuwFnoycgXfElmcg(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·g2BeySuwFnoycgXfElmcg(SB)FUNCDATA $1, gclocals·g2BeySuwFnoycgXfElmcg(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·g2BeySuwFnoycgXfElmcg(SB)FUNCDATA $1, gclocals·g2BeySuwFnoycgXfElmcg(SB)FUNCDATA $5, main.Add.arginfo1(SB)MOVW main.x(FP), R0MOVW main.y4(FP), R1ADD R1, R0, R0MOVW R0, main.~r08(FP)JMP (R14)TEXT main.main(SB), LEAF|NOFRAME|ABIInternal, $-4-0FUNCDATA $0, gclocals·g2BeySuwFnoycgXfElmcg(SB)FUNCDATA $1, gclocals·g2BeySuwFnoycgXfElmcg(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·g2BeySuwFnoycgXfElmcg(SB) 1、这是一个 FUNCDATA 伪指令用于插入与垃圾回收garbage collection相关的元数据。 2、$0 表示这段元数据的索引值为 0参数位0 X 3、gclocals·g2BeySuwFnoycgXfElmcg(SB) 是一个符号名它引用了一个包含局部变量和参数信息的数据结构。 第三句 Go 汇编指令 FUNCDATA $1, gclocals·g2BeySuwFnoycgXfElmcg(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 的值复制到 $3ATT汇编风格是 操作数 原操作数, 目标操作数 加法实现 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 问题。
http://www.hkea.cn/news/14276826/

相关文章:

  • 如何快速用手机做网站wordpress 删除修订版本
  • 网站设计书籍哈尔滨城乡建设厅网站
  • 网站管理建设总结网站建设归哪个部门
  • 北京建设局网站首页制作公司主页
  • 网站优化流程图众筹网站怎么做
  • 网站怎么做uc整合字牌标识公司网站网站编号 6019
  • 做黏土的网站网站制作知名公司
  • 网站如何建设与安全那有名网站是php做的
  • 天津武清网站开发阿里云域名注册官网
  • 用DW做网站时怎么在新窗口打开做企业网站需要建多大的画布
  • 重庆网站制作系统前端培训多少钱
  • 前端搜索网站引擎怎么做平台式建站
  • 天台县低价网站建设电子商务网站建设原则
  • 电子商务网站建设与实践重庆市建设网站
  • 来宾住房和建设局网站楼网络规划设计方案
  • 如何做网站搬家江苏建设工程信息网一体化平台官网
  • 做电商网站都需要学什么工业设计网站排名
  • 专业建站服务公司营销推广方案模板
  • 搭建网站费用wordpress的seo如何写关键词
  • 临沂专业网站建设公司哪家好聚名网域名转出
  • 阿里云怎么做网站小型企业网站建设的背景
  • 担保网站建设电商app开发价格表
  • 网站建设中应注意的问题网站建设费需要缴纳印花税吗
  • 晋中市住房与城乡建设厅网站网站开发工程师 课程大纲
  • 网站设计报价是多少有什么网站可以做毕业影像
  • 校园网站建设开题报告国外公司网站模板
  • 石家庄网站推广排名站长做旅游网站
  • 北京网站开发费用石家庄最新消息今天
  • 长春平原网站建设腾讯企业邮箱登录入口二维码
  • 网站建设公司推荐西安建设网站电话