1 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超4個(gè)贊
Go 不執(zhí)行文件 I/O,它將任務(wù)委托給操作系統(tǒng)。請(qǐng)參閱 Go 操作系統(tǒng)依賴(lài)syscall
包。
Linux 和 Windows 是具有不同 OS ABI 的不同操作系統(tǒng)。例如,Linux 使用系統(tǒng)調(diào)用 viasyscall.Syscall
而 Windows 使用 Windows dll。在 Windows 上,dll 調(diào)用是 C 調(diào)用。它不使用cgo
. 它不會(huì)去通過(guò)使用相同的動(dòng)態(tài)的C指針檢查cgo
,runtime.cgocall
。沒(méi)有runtime.wincall
別名。
綜上所述,不同的操作系統(tǒng)有不同的操作系統(tǒng)調(diào)用機(jī)制。
Go 是一種垃圾收集語(yǔ)言,垃圾收集器需要知道每個(gè)指向 Go 內(nèi)存的指針的位置。因此,在 Go 和 C 之間傳遞指針存在限制。
在本節(jié)中,術(shù)語(yǔ) Go 指針表示指向由 Go 分配的內(nèi)存的指針(例如通過(guò)使用 & 運(yùn)算符或調(diào)用預(yù)定義的新函數(shù)),術(shù)語(yǔ) C 指針表示指向由 C 分配的內(nèi)存的指針(例如通過(guò)調(diào)用C.malloc)。一個(gè)指針是 Go 指針還是 C 指針是由內(nèi)存分配方式?jīng)Q定的動(dòng)態(tài)屬性;它與指針的類(lèi)型無(wú)關(guān)。
如果 Go 代碼指向的 Go 內(nèi)存不包含任何 Go 指針,則 Go 代碼可以將 Go 指針傳遞給 C。C 代碼必須保留這個(gè)屬性:它不能在 Go 內(nèi)存中存儲(chǔ)任何 Go 指針,即使是臨時(shí)的。當(dāng)傳遞指向結(jié)構(gòu)體中字段的指針時(shí),所討論的 Go 內(nèi)存是該字段占用的內(nèi)存,而不是整個(gè)結(jié)構(gòu)體。當(dāng)傳遞指向數(shù)組或切片中元素的指針時(shí),所討論的 Go 內(nèi)存是整個(gè)數(shù)組或切片的整個(gè)后備數(shù)組。
C 代碼可能不會(huì)在調(diào)用返回后保留 Go 指針的副本。
C 代碼調(diào)用的 Go 函數(shù)可能不會(huì)返回 Go 指針。C 代碼調(diào)用的 Go 函數(shù)可能以 C 指針作為參數(shù),它可能通過(guò)這些指針存儲(chǔ)非指針或 C 指針數(shù)據(jù),但它可能不會(huì)在 C 指針指向的內(nèi)存中存儲(chǔ) Go 指針。C 代碼調(diào)用的 Go 函數(shù)可以將 Go 指針作為參數(shù),但它必須保留它所指向的 Go 內(nèi)存不包含任何 Go 指針的屬性。
Go 代碼可能不會(huì)在 C 內(nèi)存中存儲(chǔ) Go 指針。C 代碼可以將 Go 指針存儲(chǔ)在 C 內(nèi)存中,受上述規(guī)則的約束:當(dāng) C 函數(shù)返回時(shí),它必須停止存儲(chǔ) Go 指針。
這些規(guī)則在運(yùn)行時(shí)動(dòng)態(tài)檢查。檢查由 GODEBUG 環(huán)境變量的 cgocheck 設(shè)置控制。默認(rèn)設(shè)置是 GODEBUG=cgocheck=1,它實(shí)現(xiàn)了相當(dāng)便宜的動(dòng)態(tài)檢查??梢允褂?GODEBUG=cgocheck=0 完全禁用這些檢查。通過(guò) GODEBUG=cgocheck=2 可以在運(yùn)行時(shí)以一定的代價(jià)完成指針處理的檢查。
可以通過(guò)使用 unsafe 包來(lái)破壞這種強(qiáng)制執(zhí)行,當(dāng)然沒(méi)有什么可以阻止 C 代碼做任何它喜歡的事情。然而,違反這些規(guī)則的程序很可能會(huì)以意想不到和不可預(yù)測(cè)的方式失敗。
“這些規(guī)則在運(yùn)行時(shí)動(dòng)態(tài)檢查?!?/p>
基準(zhǔn):
換句話(huà)說(shuō),有謊言、該死的謊言和基準(zhǔn)。
為了跨操作系統(tǒng)進(jìn)行有效比較,您需要在相同的硬件上運(yùn)行。例如,CPU、內(nèi)存和 Rust 或硅磁盤(pán) I/O 之間的差異。我在同一臺(tái)機(jī)器上雙引導(dǎo) Linux 和 Windows。
連續(xù)運(yùn)行基準(zhǔn)測(cè)試至少 3 次。操作系統(tǒng)試圖變得智能。例如,緩存 I/O。使用虛擬機(jī)的語(yǔ)言需要預(yù)熱時(shí)間。等等。
知道你在測(cè)量什么。如果您正在執(zhí)行順序 I/O,您幾乎將所有時(shí)間都花在操作系統(tǒng)上。您是否關(guān)閉了惡意軟件保護(hù)?等等。
等等。
以下是disk.go
使用雙引導(dǎo) Windows 和 Linux 的同一臺(tái)機(jī)器的一些結(jié)果。
視窗:
>go build disk.go
>/TimeMem disk
Duration : 18.3300322s
Elapsed time : 18.38
Kernel time : 13.71 (74.6%)
User time : 4.62 (25.1%)
Linux:
$ go build disk.go
$ time ./disk
Duration : 18.54350723s
real 0m18.547s
user 0m2.336s
sys 0m16.236s
實(shí)際上,它們是相同的,disk.go持續(xù)時(shí)間為18 秒。操作系統(tǒng)之間只是在計(jì)算用戶(hù)時(shí)間和計(jì)算內(nèi)核或系統(tǒng)時(shí)間方面有所不同。流逝時(shí)間或?qū)崟r(shí)時(shí)間是相同的。
在您的測(cè)試中,內(nèi)核或系統(tǒng)時(shí)間分別為 93.72% runtime.cgocall和 95.49% syscall.Syscall。
- 1 回答
- 0 關(guān)注
- 162 瀏覽
添加回答
舉報(bào)