成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 源碼里的這些 //go: 指令,你知道嗎?

開(kāi)發(fā) 架構(gòu)
如果你平時(shí)有翻看源碼的習(xí)慣,你肯定會(huì)發(fā)現(xiàn)。咦,怎么有的方法上面總是寫(xiě)著 //go: 這類指令呢。他們到底是干嘛用的?

[[434257]]

大家好,我是煎魚(yú)。

如果你平時(shí)有翻看源碼的習(xí)慣,你肯定會(huì)發(fā)現(xiàn)。咦,怎么有的方法上面總是寫(xiě)著 //go: 這類指令呢。他們到底是干嘛用的?

今天和大家一同揭開(kāi)他們的面紗,我將給你介紹一下他們的作用都是什么。

go:linkname

  1. //go:linkname localname importpath.name 

該指令指示編譯器使用 importpath.name 作為源代碼中聲明為 localname 的變量或函數(shù)的目標(biāo)文件符號(hào)名稱。但是由于這個(gè)偽指令,可以破壞類型系統(tǒng)和包模塊化,只有引用了 unsafe 包才可以使用。

簡(jiǎn)單來(lái)講,就是 importpath.name 是 localname 的符號(hào)別名,編譯器實(shí)際上會(huì)調(diào)用 localname。

使用的前提是使用了 unsafe 包才能使用。

案例

time/time.go

  1. ... 
  2. func now() (sec int64, nsec int32, mono int64) 

runtime/timestub.go

  1. import _ "unsafe" // for go:linkname 
  2.  
  3. //go:linkname time_now time.now 
  4. func time_now() (sec int64, nsec int32, mono int64) { 
  5.  sec, nsec = walltime() 
  6.  return sec, nsec, nanotime() - startNano 

在這個(gè)案例中可以看到 time.now,它并沒(méi)有具體的實(shí)現(xiàn)。如果你初看可能會(huì)懵逼。這時(shí)候建議你全局搜索一下源碼,你就會(huì)發(fā)現(xiàn)其實(shí)現(xiàn)在 runtime.time_now 中。

配合先前的用法解釋,可得知在 runtime 包中,我們聲明了 time_now 方法是 time.now 的符號(hào)別名。并且在文件頭引入了 unsafe 達(dá)成前提條件。

go:noescape

  1. //go:noescape 

該指令指定下一個(gè)有聲明但沒(méi)有主體(意味著實(shí)現(xiàn)有可能不是 Go)的函數(shù),不允許編譯器對(duì)其做逃逸分析。

一般情況下,該指令用于內(nèi)存分配優(yōu)化。編譯器默認(rèn)會(huì)進(jìn)行逃逸分析,會(huì)通過(guò)規(guī)則判定一個(gè)變量是分配到堆上還是棧上。

但凡事有意外,一些函數(shù)雖然逃逸分析其是存放到堆上。但是對(duì)于我們來(lái)說(shuō),它是特別的。我們就可以使用 go:noescape 指令強(qiáng)制要求編譯器將其分配到函數(shù)棧上。

案例

  1. // memmove copies n bytes from "from" to "to"
  2. // in memmove_*.s 
  3. //go:noescape 
  4. func memmove(tofrom unsafe.Pointer, n uintptr) 

我們觀察一下這個(gè)案例,它滿足了該指令的常見(jiàn)特性。如下:

  • memmove_*.s:只有聲明,沒(méi)有主體。其主體是由底層匯編實(shí)現(xiàn)的
  • memmove:函數(shù)功能,在棧上處理性能會(huì)更好

go:nosplit

  1. //go:nosplit 

該指令指定文件中聲明的下一個(gè)函數(shù)不得包含堆棧溢出檢查。

簡(jiǎn)單來(lái)講,就是這個(gè)函數(shù)跳過(guò)堆棧溢出的檢查。

案例

  1. //go:nosplit 
  2. func key32(p *uintptr) *uint32 { 
  3.  return (*uint32)(unsafe.Pointer(p)) 

go:nowritebarrierrec

  1. //go:nowritebarrierrec 

該指令表示編譯器遇到寫(xiě)屏障時(shí)就會(huì)產(chǎn)生一個(gè)錯(cuò)誤,并且允許遞歸。也就是這個(gè)函數(shù)調(diào)用的其他函數(shù)如果有寫(xiě)屏障也會(huì)報(bào)錯(cuò)。

簡(jiǎn)單來(lái)講,就是針對(duì)寫(xiě)屏障的處理,防止其死循環(huán)。

案例

  1. //go:nowritebarrierrec 
  2. func gcFlushBgCredit(scanWork int64) { 
  3.     ... 

go:yeswritebarrierrec

  1. //go:yeswritebarrierrec 

該指令與 go:nowritebarrierrec 相對(duì),在標(biāo)注 go:nowritebarrierrec 指令的函數(shù)上,遇到寫(xiě)屏障會(huì)產(chǎn)生錯(cuò)誤。

而當(dāng)編譯器遇到 go:yeswritebarrierrec 指令時(shí)將會(huì)停止。

案例

  1. //go:yeswritebarrierrec 
  2. func gchelper() { 
  3.  ... 

go:noinline

該指令表示該函數(shù)禁止進(jìn)行內(nèi)聯(lián)。

案例

  1. //go:noinline 
  2. func unexportedPanicForTesting(b []byte, i int) byte { 
  3.  return b[i] 

我們觀察一下這個(gè)案例,是直接通過(guò)索引取值,邏輯比較簡(jiǎn)單。如果不加上 go:noinline 的話,就會(huì)出現(xiàn)編譯器對(duì)其進(jìn)行內(nèi)聯(lián)優(yōu)化。

顯然,內(nèi)聯(lián)有好有壞。該指令就是提供這一特殊處理。

go:norace

  1. //go:norace 

該指令表示禁止進(jìn)行競(jìng)態(tài)檢測(cè)。

常見(jiàn)的形式就是在啟動(dòng)時(shí)執(zhí)行 go run -race,能夠檢測(cè)應(yīng)用程序中是否存在雙向的數(shù)據(jù)競(jìng)爭(zhēng),非常有用。

案例

  1. //go:norace 
  2. func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) { 
  3.     ... 

go:notinheap

  1. //go:notinheap 

該指令常用于類型聲明,它表示這個(gè)類型不允許從 GC 堆上進(jìn)行申請(qǐng)內(nèi)存。

在運(yùn)行時(shí)中常用其來(lái)做較低層次的內(nèi)部結(jié)構(gòu),避免調(diào)度器和內(nèi)存分配中的寫(xiě)屏障,能夠提高性能。

案例

 

  1. // notInHeap is off-heap memory allocated by a lower-level allocator 
  2. // like sysAlloc or persistentAlloc. 
  3. // 
  4. // In general, it's better to use real types marked as go:notinheap, 
  5. // but this serves as a generic type for situations where that isn't 
  6. // possible (like in the allocators). 
  7. // 
  8. //go:notinheap 
  9. type notInHeap struct{} 

 

總結(jié)

在本文我們簡(jiǎn)單介紹了一些常見(jiàn)的指令集,讓大家有了整體的系統(tǒng)了解。這些指令平時(shí)在 Go 工程中我們是用不到的,常見(jiàn)的瓶頸可能更多的在自身應(yīng)用上。

 

不過(guò)在了解了這些機(jī)制后,對(duì)你閱讀 Go 語(yǔ)言底層源碼和了解運(yùn)行機(jī)制會(huì)很有幫助 :)

 

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚(yú)了
相關(guān)推薦

2024-09-02 00:30:41

Go語(yǔ)言場(chǎng)景

2024-10-09 08:54:31

2020-10-28 11:20:55

vue項(xiàng)目技

2021-05-31 10:22:09

Go語(yǔ)言代碼

2022-01-05 11:40:36

Go特性語(yǔ)言

2022-10-24 09:57:02

runeGo語(yǔ)言

2020-11-18 07:52:08

2020-12-24 15:26:07

Redis數(shù)據(jù)庫(kù)

2018-05-11 15:53:59

2021-08-05 18:21:29

Autowired代碼spring

2014-05-30 10:23:15

樂(lè)跑手環(huán)智能手環(huán)運(yùn)動(dòng)手環(huán)

2024-08-19 00:00:02

2015-06-29 09:06:51

2019-02-12 11:15:15

Spring設(shè)計(jì)模式Java

2018-02-06 09:40:25

PythonOOP繼承

2018-03-07 06:37:14

開(kāi)源項(xiàng)目源代碼云計(jì)算

2019-07-08 10:18:38

MPLSIP數(shù)據(jù)

2023-01-16 08:09:51

SpringMVC句柄

2022-05-11 09:04:50

Go函數(shù)數(shù)組

2016-03-18 19:03:35

認(rèn)知計(jì)算IBM
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩成人精品在线 | 欧美a级成人淫片免费看 | av不卡一区| 视频一区二区中文字幕日韩 | 日韩毛片视频 | 亚洲精品在线91 | 国产精品一区二 | 亚洲欧美一区二区三区在线 | 亚洲午夜在线 | 日韩国产精品一区二区三区 | 精品欧美一区二区在线观看欧美熟 | 国产日韩欧美 | 久久精品国产免费高清 | 99精品视频免费在线观看 | 毛片久久久 | 亚洲一区二区视频 | 国产在线一区二区三区 | 欧美日韩国产精品一区 | 亚洲自拍一区在线观看 | 色偷偷噜噜噜亚洲男人 | 国产一区二区免费 | 自拍偷拍精品 | 国产亚洲成av人片在线观看桃 | 久久蜜桃av一区二区天堂 | 蜜桃综合在线 | 国产成人精品一区二区 | 国产亚洲精品a | 中文字字幕一区二区三区四区五区 | 亚洲精品一区中文字幕乱码 | 一区二区久久 | 先锋av资源在线 | 久久日韩精品一区二区三区 | av毛片 | 二区欧美 | 免费激情 | 黄片毛片 | 国产高清视频 | 久久久久久国产精品 | 成人免费在线观看 | 婷婷久久网 | 久久国产高清视频 |