中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

手機(jī)端網(wǎng)站制作seo推廣有哪些

手機(jī)端網(wǎng)站制作,seo推廣有哪些,成都百度推廣的關(guān)鍵詞,手機(jī)版網(wǎng)站制作應(yīng)用參考: Go 匯編函數(shù) - Go 語言高級編程 Go 嵌套匯編 - 掘金 (juejin.cn) 前言: Golang 適用 Go-Runtime(Go 運(yùn)行時(shí),嵌入在被編譯的PE可執(zhí)行文件之中)來管理調(diào)度協(xié)同程式的運(yùn)行。 Go 語言沒有多線程(MT&a…

參考:?

Go 匯編函數(shù) - Go 語言高級編程

Go 嵌套匯編 - 掘金 (juejin.cn)

前言:

Golang 適用 Go-Runtime(Go 運(yùn)行時(shí),嵌入在被編譯的PE可執(zhí)行文件之中)來管理調(diào)度協(xié)同程式的運(yùn)行。

Go 語言沒有多線程(MT)的概念,在 Go 語言之中,每個(gè) Go 協(xié)程就類似開辟了一個(gè)新的線程,效率上,肯定是比分配線程好的。

但也僅限于分配協(xié)程,及單個(gè)進(jìn)程可以跑幾萬個(gè)乃至幾十萬個(gè)協(xié)同程序,這是線程無法比擬的,因?yàn)樵诓僮飨到y(tǒng)之中,最小執(zhí)行單元的單位就是線程了,但是線程相對協(xié)同程序來說,過重,無論是內(nèi)存還是CPU。

但不意味著 Go 協(xié)程執(zhí)行的效率比線程要好,別太自信與盲目,協(xié)程是比不了線程代碼CPU執(zhí)行效率的。

上面也提到了,只是可以同時(shí)開辟幾萬個(gè)乃至幾十萬個(gè)協(xié)程,并且啟動協(xié)程速度比線程快非常多,這是它的優(yōu)勢,但是缺點(diǎn)也很明顯,在物理線程上執(zhí)行 Go 協(xié)同程式的代碼效率不高。

目前世界上最快的協(xié)同程序切換,應(yīng)該是 C/C++ 之中的:

State Threads Library (sourceforge.net)

boost::context?

兩個(gè)庫各有千秋,但相對來說 boost 更好用一些,在這里需要提醒大家一點(diǎn),應(yīng)用程序之中運(yùn)行協(xié)同程序,它是依托于進(jìn)程之中的物理線程上執(zhí)行的。

來到正題,我們先來探討 Golang 到底是 “Stackless” 無棧輕量協(xié)程,還是 “Stackful” 有棧重量協(xié)程呢?

那么就有必要分析清楚,有棧協(xié)程跟無棧協(xié)程之間到底有什么區(qū)別。

首先:

1、有棧協(xié)程

? ? ? 1.1、棧協(xié)程是一種基于線程或進(jìn)程的協(xié)程實(shí)現(xiàn)方式。

? ? ? 1.2、棧協(xié)程擁有自己的執(zhí)行棧,可以獨(dú)立地管理?xiàng)?、局部變量和函?shù)調(diào)用。

? ? ? 1.3、棧協(xié)程的切換需要保存和恢復(fù)整個(gè)執(zhí)行上下文,包括棧指針、寄存器等。

? ? ? 1.4、由于棧協(xié)程具有獨(dú)立的執(zhí)行棧,因此它們可以支持遞歸調(diào)用和深度嵌套。

? ? ? 1.5、由于棧協(xié)程需要額外的資源來維護(hù)棧,因此在創(chuàng)建和銷毀方面可能會有一些開銷。?

2、無棧協(xié)程

? ? ? 2.1、無棧協(xié)同是一種基于用戶空間的協(xié)程實(shí)現(xiàn)方式。

? ? ? 2.2、無棧協(xié)同沒有獨(dú)立的執(zhí)行棧,它們共享相同的調(diào)用棧?!局攸c(diǎn)】

? ? ? 2.3、無棧協(xié)同使用狀態(tài)機(jī)來管理協(xié)程的執(zhí)行,并通過保存和恢復(fù)狀態(tài)來實(shí)現(xiàn)協(xié)程的切換。

? ? ? 2.4、由于無棧協(xié)同共享調(diào)用棧,因此它們不能支持遞歸調(diào)用和深度嵌套。

? ? ? 2.5、無棧協(xié)同通常比棧協(xié)程更輕量級,創(chuàng)建和銷毀開銷較小。

似乎從上述定義的概念來說,Golang 是有棧協(xié)議?但真的是這樣嗎?顯然不是的,首先真正意義上的有棧協(xié)程,是無法被運(yùn)行時(shí)代管的。

有棧協(xié)程存在以下幾個(gè)限制:

1、如果開發(fā)人員切換協(xié)程處理不當(dāng)?shù)那闆r下,會導(dǎo)致協(xié)程棧內(nèi)存泄漏問題。

2、如果開發(fā)人員在多個(gè)線程之中執(zhí)行

3、有棧協(xié)程無法動態(tài)擴(kuò)展計(jì)算??臻g,所以有棧協(xié)程需要在分配時(shí),明確指定棧空間大小。

一個(gè)協(xié)同程序可以在多個(gè)線程上按保證順序性(時(shí)序)進(jìn)行處理,無論是有棧協(xié)同程序、或者是無棧協(xié)同程序,均可以。

Go 協(xié)同程序是屬于 “Stackless” 無棧協(xié)程的類型,但 Go 為了實(shí)現(xiàn)協(xié)同程序能像 Stackful 有棧協(xié)程一樣,擁有屬于自己的外掛棧空間,并且支持動態(tài)??臻g擴(kuò)容。

但要注意一點(diǎn):

1、Go 協(xié)程可能在不同的線程上面被執(zhí)行,雖然 Go 語言運(yùn)行時(shí)保證了,單一協(xié)同程序執(zhí)行的時(shí)序性,但開發(fā)人員需要在其中注意協(xié)同程序之間的同步問題,類似多線程并發(fā)編程。

2、若要實(shí)現(xiàn)同步鎖的情況,人們需要考慮多線程問題,否則這可能造成很嚴(yán)重的后果,即 Go 運(yùn)行時(shí)附著的工作線程被阻塞,同時(shí)最好的實(shí)現(xiàn)方式偽同步鎖,如利用管道來實(shí)現(xiàn)類似效果。

相對傳統(tǒng)的 TTASLock/CAS自選鎖實(shí)現(xiàn),可能不太適合Go 這種結(jié)構(gòu)的程序,這是因?yàn)?#xff1a;Go 協(xié)同程序在沒有執(zhí)行異步的情況下是不會讓出線程CPU的,你可以理解為,你需要執(zhí)行類似文件IO、網(wǎng)絡(luò)IO、或者調(diào)用 Go 運(yùn)行時(shí)庫之中的同步庫,例如:sync.Mutex 產(chǎn)生了阻塞行為

鑒于?Go 運(yùn)行時(shí)是多線程執(zhí)行,在不阻塞 Go 運(yùn)行時(shí)最大工作線程的情況下,其它協(xié)程,仍舊是可以正常就緒的工作的,這取決于運(yùn)行時(shí)調(diào)度。

所以嚴(yán)格意義上來說,Go 協(xié)程屬于 “Stackless” + “Stackful” 的變種協(xié)程,它屬于 “Stackless” 無棧協(xié)同程序的一種,但 Go 編譯器實(shí)現(xiàn)對其用戶代碼進(jìn)行展開,并分配一個(gè) “Go 外掛計(jì)算棧內(nèi)存空間單元”,而非真正意義上的函數(shù)棧,如同C#、C++、C#、ASM、IL函數(shù)的調(diào)用堆棧。

有棧協(xié)程無法放大執(zhí)行堆棧的根本原因是寄存器,EIP、RIP,及地址鏈之間存在上下依賴問題等等,Go 并非是真的有棧協(xié)程,自然不會存在這個(gè)問題,它本來就是由編譯器支持的黑魔法,實(shí)現(xiàn)的協(xié)同程序(“重點(diǎn):最終會被展開編譯為狀態(tài)機(jī)切換的”),但這類編譯器不能編譯過度復(fù)雜協(xié)同應(yīng)用程序,雖然我個(gè)人是相信 Google 的技術(shù)水平的,但并不代表,不對 Stackless 協(xié)程先天存在的對于編譯器的復(fù)雜性,感到一絲憂慮,這個(gè)世界上不存在完美的技術(shù),這類編譯器完全內(nèi)部實(shí)現(xiàn)的純純黑盒,對開發(fā)人員來說不太容易掌控到更多的細(xì)節(jié)。

Go 通過外掛計(jì)算??臻g的解決方案,在該 Go 棧空間內(nèi)不保存任何寄存器之類的值,僅存儲調(diào)用函數(shù)棧幀的元RID、參數(shù)、變量等(值或引用),所以在棧空間不足時(shí),進(jìn)行擴(kuò)大外掛棧時(shí)。

即:分配新的??臻g內(nèi)存,并把原棧內(nèi)存復(fù)制過來,在釋放原棧內(nèi)存空間的內(nèi)存,并把新的棧內(nèi)存首地址(指針)掛載到當(dāng)前 Go 協(xié)同程序的棧頂指針、棧底指針。

在復(fù)制并放大?Go 協(xié)程棧內(nèi)存空間的時(shí)候,會導(dǎo)致該協(xié)同被同步阻塞,恢復(fù)取決于這個(gè)步驟在何時(shí)完成。

Go 棧空間雖然不會保存寄存器的值,但并不意味著 Go 程序不會適用目標(biāo)平臺匯編指令集

下述是一個(gè)很簡單的 Go 加法函數(shù),返回參數(shù) 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

從上述的代碼中,我們可以清晰的看到,出現(xiàn)了并非X86/X64匯編語法的,FUNCDATA 、PCDATA? 兩個(gè)指令。

它們是 GO 匯編之中的偽指令,注意它是偽指令,意思就是說這東西不能用,除了GO的編譯器能理解它之外,其它的匯編器,無論 GCC、VC++ 都是不認(rèn)識這個(gè)東西。

人們可以理解,Go 存在兩個(gè)編譯過程,一個(gè)前端編譯器,一個(gè)后端編譯器,前端編譯器就是把我們寫的 .go 源文件的程序代碼編譯為 Go 后端編譯器認(rèn)識的 Go 匯編指令集代碼。

這的確很類似于 JAVA/JVM 編譯的字節(jié)碼、C# 編譯器的 MSIL 中間指令代碼,但又存在明顯的區(qū)別,人們可以顯著的參考下述在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)

人們可以明顯的看到,除了幾個(gè)偽指令是相同他的,但是內(nèi)部實(shí)現(xiàn)所使用的指令發(fā)生了變化,這是因?yàn)?#xff0c;Go 每個(gè)平臺編譯器生成的 Go 匯編代碼會根據(jù)CPU指令集平臺的不同而不同,這是因?yàn)?Go 雖然編譯的是只能給 Go 后端編譯器看的匯編代碼。

但不意味著它會完全按照先編譯為字節(jié)碼、中間代碼的形式,Go 前端編譯器輸出的 Go 匯編,在編譯的過程中,就已經(jīng)按照目的平臺的指令集進(jìn)行了一部分的翻譯(不完全是真匯編,但匯編已很接近了。)

剩下那部分偽指令是讓 Go 匯編器,在構(gòu)建目的程序時(shí),所需處理的東西,就是GC、外掛棧空間內(nèi)存上面的參數(shù)、局部變量讀取這些實(shí)現(xiàn),最后生成的目的匯編代碼,才是用來編譯為目的PE、ELF可執(zhí)行文件的。

OK:這里簡單的描述下上面X86匯編的意義,ARM我不怎么看得懂,所以不在此處獻(xiàn)丑了

第一句 Go 匯編指令:

TEXT ? ?main.Add(SB), NOSPLIT|NOFRAME|ABIInternal, $0-16

1、TEXT: 這是一個(gè)偽指令,用于指示下面的代碼是函數(shù)代碼(類似于其他匯編語言中的函數(shù)標(biāo)簽)。

2、main.Add(SB): main.Add 是函數(shù)的名稱,SB 表示 Static Base(靜態(tài)基址),它是一個(gè)匯編符號,指示函數(shù)相對于全局?jǐn)?shù)據(jù)區(qū)的偏移量。

3、NOSPLIT|NOFRAME|ABIInternal: 這是函數(shù)的屬性標(biāo)志。NOSPLIT 指示編譯器不應(yīng)在函數(shù)內(nèi)插入棧分裂代碼,NOFRAME 指示編譯器不應(yīng)創(chuàng)建函數(shù)堆棧幀,ABIInternal 表示該函數(shù)的調(diào)用約定為 Go 內(nèi)部使用。

4、$0-16: 這是函數(shù)的棧幀大小指令。$0 表示該函數(shù)不會在棧上分配任何局部變量的空間,-16 表示函數(shù)會從參數(shù)中讀取16字節(jié)的數(shù)據(jù)。

注意:這個(gè)??臻g指的是 Go 程序外掛的棧哈,不是進(jìn)程線程的??臻g。(或?yàn)樘摂M??臻g)

第二句 Go 匯編指令:

FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)

1、這是一個(gè) FUNCDATA 偽指令,用于插入與垃圾回收(garbage collection)相關(guān)的元數(shù)據(jù)。

2、$0 表示這段元數(shù)據(jù)的索引值為 0(參數(shù)位:0 = X)

3、gclocals·g2BeySu+wFnoycgXfElmcg==(SB) 是一個(gè)符號名,它引用了一個(gè)包含局部變量和參數(shù)信息的數(shù)據(jù)結(jié)構(gòu)。

第三句 Go 匯編指令:

FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)

跟第二句沒區(qū)別,元數(shù)據(jù)索引值為 1(參數(shù)位:1 = Y)

第四句 Go 匯編指令:

FUNCDATA $5, main.Add.arginfo1(SB)

main.Add.arginfo1(SB) 是獲取 “描述函數(shù)參數(shù)類型和數(shù)量的數(shù)據(jù)結(jié)構(gòu)的引用地址”。

Go 語言沒有顯示的函數(shù)簽名聲明,所以編譯器需要這個(gè)函數(shù)的參數(shù)信息,以便于可以正確的傳遞參數(shù)值給該函數(shù)。

第五句?Go 匯編指令:

FUNCDATA $6, main.Add.argliveinfo(SB)

main.Add.argliveinfo(SB) 是獲取 “描述函數(shù)參數(shù)活躍性的數(shù)據(jù)結(jié)構(gòu)的引用地址”

參數(shù)的活躍性指的是在函數(shù)執(zhí)行期間哪些參數(shù)被使用了。這些信息對于優(yōu)化代碼的執(zhí)行效率非常重要,GO GC在用。

第六句 Go 匯編指令

PCDATA  $3, $1

把 $1?的值復(fù)制到 $3,AT&T匯編風(fēng)格是:

操作數(shù) 原操作數(shù), 目標(biāo)操作數(shù)

加法實(shí)現(xiàn) GO 匯編指令

ADDQ    BX, AX
RET

1、AX 和 BX 寄存器用于存儲 x 和 y 的值。

2、之后,通過 ADDQ BX, AX 指令將 y 的值加到 x 上,并將結(jié)果保存在 AX 寄存器中。

3、最后,使用 RET 指令將結(jié)果返回。

總結(jié):

1、Golang 協(xié)程不會保存CPU寄存器的值。

2、Golang 協(xié)程屬于 Stackless 協(xié)程的一種變種。

3、Golang 通過為外掛計(jì)算棧內(nèi)存空間,來實(shí)現(xiàn)類似有棧協(xié)程的效果。

4、Golang 兩個(gè)協(xié)程可能在不同的物理線程上面工作,所以公用數(shù)據(jù)訪問時(shí),須注意同步問題。

5、Golang 協(xié)程在處理異步操作的時(shí),讓出了當(dāng)前協(xié)程占用的線程CPU,協(xié)程處于WAIT狀態(tài)時(shí), 當(dāng)前協(xié)程依賴的外部數(shù)據(jù),可能在外部發(fā)生了改變或者釋放。

? ? ? 所以,該協(xié)程被喚醒之后(resume\awake)理應(yīng)檢查當(dāng)前依賴數(shù)據(jù)的狀態(tài),如:在該協(xié)程處于 Yield 等待狀態(tài)之中時(shí),其它協(xié)程調(diào)用了 Dispose 函數(shù),釋放了 “它(公用數(shù)據(jù))” 持有的全部被托管及非托管資源。

6、Golang 也會適用寄存器優(yōu)化,但這有一些前提,就是簡單的算術(shù)運(yùn)算,可以被編譯為寄存器優(yōu)化的代碼,這不沖突,只是最終會把值存儲到 “Go” 為每個(gè)協(xié)程分配的外掛棧內(nèi)存空間上面。

就像在 MSIL 之中,人們執(zhí)行 stloc.s、ldloc.s、ldarg.s、starg.s 這些指令集一樣,只不過它不像微軟的 .NET CLR 會把這些代碼編譯為近似 C/C++ 編譯器輸出的目標(biāo)平臺匯編代碼,當(dāng)然不管怎么做,這類由GC系統(tǒng)標(biāo)記的語言,都會在最終編譯輸出的匯編代碼之中插入引用技術(shù)管理的實(shí)現(xiàn),區(qū)別是在什么地方插入,當(dāng)然這的看GC系統(tǒng)是怎么設(shè)計(jì)的,比如鏈?zhǔn)奖闅v的GC,就不需要在每個(gè)函數(shù)引用資源的地方去做 AddRef、到結(jié)尾做 ReleaseRef 這樣的行為,但缺點(diǎn)就是GC在處理終結(jié)的時(shí)候,CPU開銷比較大。

7、Golang 之中托管資源是通過RID間接引用的,即托管資源并非是直接使用指針,這是因?yàn)橘Y源或會被GC壓縮或移動碎片整理,當(dāng)然這個(gè)時(shí)候會導(dǎo)致阻塞問題,即:GC Pinned 問題。

http://www.risenshineclean.com/news/61743.html

相關(guān)文章:

  • 外管局網(wǎng)站做延期收匯報(bào)告推廣排名seo
  • 怎么樣自己做網(wǎng)站賺錢年入40萬百度推廣代理商加盟
  • wordpress includeseo網(wǎng)站分析
  • wordpress出現(xiàn)兩個(gè)首頁關(guān)鍵詞優(yōu)化的最佳方法
  • 佛山移動網(wǎng)站建設(shè)公司seo搜索優(yōu)化公司
  • 服務(wù)器在美國的網(wǎng)站seosem是指什么意思
  • 北京h5網(wǎng)站開發(fā)公司北京網(wǎng)站
  • 我?guī)驮p騙團(tuán)伙做詐騙網(wǎng)站獲利留電話的廣告網(wǎng)站
  • 武漢教育網(wǎng)站建設(shè)優(yōu)化發(fā)帖平臺
  • 網(wǎng)頁建設(shè)類有哪些軟件seo營銷
  • 織夢手機(jī)網(wǎng)站制作教程seo站長平臺
  • ts wordpress網(wǎng)站優(yōu)化建議
  • 網(wǎng)站流量 名詞洛陽seo網(wǎng)絡(luò)推廣
  • wordpress更改前端引用關(guān)鍵詞優(yōu)化軟件哪家好
  • 阿里巴巴網(wǎng)站圖片怎么做國際時(shí)事新聞2022最新
  • 旅游網(wǎng)站開發(fā)團(tuán)隊(duì)百度廣告投放代理商
  • 南充網(wǎng)站建設(shè)公司seo 公司
  • 南通做網(wǎng)站的推廣普通話的文字內(nèi)容
  • 中國建設(shè)銀行新聞網(wǎng)站最近一周熱點(diǎn)新聞
  • 手機(jī)端企業(yè)網(wǎng)站源碼下載推廣產(chǎn)品的方式有哪些
  • notepad做網(wǎng)站網(wǎng)絡(luò)seo啥意思
  • 局域網(wǎng)網(wǎng)站開發(fā)濟(jì)南seo外包公司
  • 外包網(wǎng)站建設(shè)費(fèi)用包括網(wǎng)站備份如何制作網(wǎng)頁鏈接教程
  • wordpress 制作模板seo優(yōu)化培訓(xùn)多少錢
  • asp網(wǎng)站 seob站推廣入口2023
  • 專做短篇的網(wǎng)站百度站長工具域名查詢
  • 建網(wǎng)站程序怎么寫中小型企業(yè)網(wǎng)站設(shè)計(jì)與開發(fā)
  • 網(wǎng)站開發(fā)常見畢業(yè)設(shè)計(jì)題目互聯(lián)網(wǎng)營銷顧問
  • 建設(shè)銀行網(wǎng)站點(diǎn)擊次數(shù)百度風(fēng)云榜游戲
  • wordpress調(diào)用7天熱門文章seo優(yōu)化交流