0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于塊層的組成“bio層”的詳細(xì)解析

Linux閱碼場 ? 2018-02-03 16:23 ? 次閱讀

操作系統(tǒng)比如Linux關(guān)鍵的價(jià)值之一,就是為具體的設(shè)備提供了抽象接口。雖然后來出現(xiàn)了各種其它抽象模型比如“網(wǎng)絡(luò)設(shè)備”和“位圖顯示(bitmap display)”,但是最初的“字符設(shè)備”和“塊設(shè)備”兩種類型的設(shè)備抽象依然地位顯赫。近幾年持久化內(nèi)存(persistent memory)炙手可熱,[與非易失性存儲(chǔ)NVRAM概念不同, persistent memory強(qiáng)調(diào)以內(nèi)存訪問方式讀寫持久存儲(chǔ),完全不同與塊設(shè)備層], 但在將來很長一段時(shí)間內(nèi),塊設(shè)備接口仍然是持久存儲(chǔ)(persistent storage)的主角。這兩篇文章的目的就是去揭開這位主角的面紗。

術(shù)語“塊層”常指Linux內(nèi)核中非常重要的一部分 - 這部分實(shí)現(xiàn)了應(yīng)用程序和文件系統(tǒng)訪問存儲(chǔ)設(shè)備的接口。 塊層是由哪些代碼組成的呢? 這個(gè)問題沒有準(zhǔn)確的答案。一個(gè)最簡單的答案是在"block"子目錄下的所有源碼。這些代碼又可被看作兩層,這兩層之間緊密聯(lián)系但有明顯的區(qū)別。我知道這兩個(gè)子層次還沒有公認(rèn)的命名,因此這里就稱作“bio層”和“request 層”吧。本文將帶我們先了解"bio層",而在下一篇文章中討論“request層”。

塊層之上

在深挖bio層之前,很有必要先了解點(diǎn)背景知識(shí),看看塊層之上的天地。這里“之上”意思是靠近用戶空間(the top),遠(yuǎn)離硬件(the bottom),包括所有使用塊層服務(wù)的代碼。

基于塊層的組成“bio層”的詳細(xì)解析

通常,我們可以通過/dev目錄下的塊設(shè)備文件來訪問塊設(shè)備,在內(nèi)核中塊設(shè)備文件會(huì)映射到一個(gè)有S_IFBLK標(biāo)記的inode。這些inode有點(diǎn)像符號(hào)鏈接,本身不代表一個(gè)塊設(shè)備,而是一個(gè)指向塊設(shè)備的指針。更細(xì)地說,inode結(jié)構(gòu)體的i_bdev域會(huì)指向一個(gè)代表目標(biāo)設(shè)備的struct block_device對(duì)象。 struct block_device包含一個(gè)指向第二個(gè)inode的域:block_device->bd_inode, 這個(gè)inode會(huì)在塊設(shè)備IO中起作用,而/dev目錄下的inode只是一個(gè)指針而已。

第二個(gè)inode所起的主要作用(實(shí)現(xiàn)代碼主要在fs/block_dev.c, fs/buffer.c,等)就是提供page cache。如果設(shè)備文件打開時(shí)沒有加O_DIRECT標(biāo)志,與inode關(guān)聯(lián)的page cache用來緩存預(yù)讀數(shù)據(jù),或緩存寫數(shù)據(jù)直到回寫(writeback)過程將臟頁刷到塊設(shè)備上。如果用了O_DIRECT,讀和寫繞過page cache直接向塊設(shè)備發(fā)請(qǐng)求。相似地,當(dāng)一個(gè)塊設(shè)備格式化并掛載成文件系統(tǒng)時(shí),讀和寫操作通常會(huì)直接作用在塊設(shè)備上 [作者寫錯(cuò)了?],盡管一些文件系統(tǒng)(尤其是ext*家族)能夠訪問相同的page cache(過去稱為buffer cache)來管理一些文件系統(tǒng)數(shù)據(jù)。

open()另一個(gè)與塊設(shè)備相關(guān)的標(biāo)志是O_EXCL。塊設(shè)備有個(gè)簡單的勸告鎖(advisory-locking)模型,每個(gè)塊設(shè)備最多只能有個(gè)“持有者”(holder)。在激活一個(gè)塊設(shè)備時(shí),[激活泛指驅(qū)動(dòng)一個(gè)塊設(shè)備的過程,包括向內(nèi)核添加代表塊設(shè)備的對(duì)象,注冊(cè)請(qǐng)求隊(duì)列等],可用blkdev_get()函數(shù)為塊設(shè)備指定一個(gè)"持有者"。[ blkdev_get()的原型: int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder), holder可以是一個(gè)文件系統(tǒng)的超級(jí)塊, 也可以是一個(gè)掛載點(diǎn)等]。一旦塊設(shè)備有了“持有者”,隨后再試圖激活該設(shè)備就會(huì)失敗。通常在掛載時(shí),文件系統(tǒng)會(huì)為塊設(shè)備指定一個(gè)“持有者”,來保證互斥使用塊設(shè)備。當(dāng)一個(gè)應(yīng)用程序試圖以O(shè)_EXCL方式打開塊設(shè)備時(shí),內(nèi)核會(huì)新建一個(gè)struct file對(duì)象并把它作為塊設(shè)備的“持有者”,假如這個(gè)塊設(shè)備作為文件系統(tǒng)已經(jīng)被掛載,打開操作就會(huì)失敗。如果open()操作成功并且還沒有關(guān)上,嘗試掛載操作就會(huì)阻塞。但是,如果塊設(shè)備不是以O(shè)_EXCL打開的,那么O_EXCL就不能阻止塊設(shè)備被同時(shí)打開,O_EXCL只是便于應(yīng)用程序測試塊設(shè)備是否正在使用中。

無論以什么方式訪問塊設(shè)備,主要接口都是發(fā)送讀寫請(qǐng)求,或其它特殊請(qǐng)求比如discard操作, 最終接收處理結(jié)果。bio層就是要提供這樣的服務(wù)。

bio層

Linux中塊設(shè)備用struct gendisk表示,即 一個(gè)通用磁盤 (generic disk)。這個(gè)結(jié)構(gòu)體也沒包含太多信息,主要起承上啟下的作用,上承文件系統(tǒng),下啟塊層。往上層走,一個(gè)gendisk對(duì)象會(huì)關(guān)聯(lián)到block_device對(duì)象,如我們上文所述,block_device對(duì)象被鏈接到/dev目錄下的inode中。如果一個(gè)物理塊設(shè)備包含多個(gè)分區(qū),也就說有個(gè)分區(qū)表,那么這個(gè)gendisk對(duì)象就對(duì)應(yīng)多個(gè)block_device對(duì)象。其中,有一個(gè)block_device對(duì)象代表著整個(gè)物理磁盤gendisk,而其它block_device各代表gendisk中的一個(gè)分區(qū)。

struct bio是bio層一個(gè)重要的數(shù)據(jù)結(jié)構(gòu),用來表示來自block_device對(duì)象的讀寫請(qǐng)求,以及各種其它的控制類請(qǐng)求,然后把這些請(qǐng)求傳達(dá)到驅(qū)動(dòng)層。一個(gè)bio對(duì)象包括的信息有目標(biāo)設(shè)備,設(shè)備地址空間上的偏移量,請(qǐng)求類型(通常是讀或?qū)懀?,讀寫大小,和用來存放數(shù)據(jù)的內(nèi)存區(qū)域。在Linux 4.14之前,bio對(duì)象是用block_device來表示目標(biāo)設(shè)備的。而現(xiàn)在bio對(duì)象包含一個(gè)指向gendisk結(jié)構(gòu)體的指針和分區(qū)號(hào),這些可通過bio_set_dev()函數(shù)設(shè)置。這樣做突出了gendisk結(jié)構(gòu)體的核心地位,更自然一些。

一個(gè)bio一旦構(gòu)造好,上層代碼就可以調(diào)用generic_make_request()或submit_bio()提交給bio層處理。[submit_bio()只是generic_make_request()的一個(gè)簡單封裝]。 通常,上層代碼不會(huì)等待請(qǐng)求處理完成,而是把請(qǐng)求放到塊設(shè)備隊(duì)列上就返回了。generic_make_request()有時(shí)可能阻塞一小會(huì),比如在等待內(nèi)存分配的時(shí)候,這樣想可能更容易理解,它也許要等待一些已經(jīng)在隊(duì)列上的請(qǐng)求處理完成,然后騰出空間。如果bi_opf域上設(shè)置了REQ_NOWAIT標(biāo)志,generic_make_request()在任何情況下都不應(yīng)該阻塞,而應(yīng)該把這個(gè)bio的返回狀態(tài)設(shè)置成BLK_STS_AGAIN或BLK_STS_NOTSUPP,然后立即返回。截至寫作時(shí),這個(gè)功能還沒有完全實(shí)現(xiàn)。

bio層和request層間的接口需要設(shè)備驅(qū)動(dòng)調(diào)用blk_queue_make_request()來注冊(cè)一個(gè)make_request_fn()函數(shù),這樣generic_make_request()就可以通過回調(diào)這個(gè)函數(shù)來處理提交個(gè)這個(gè)塊設(shè)備的bio請(qǐng)求了。make_request_fn()函數(shù)負(fù)責(zé)如何處理bio請(qǐng)求,當(dāng)IO請(qǐng)求完成時(shí),調(diào)用bio_endio()設(shè)置bi_status域的狀態(tài)來表示請(qǐng)求是否處理成功,并回調(diào)保存在bio結(jié)構(gòu)體里的bi_end_io函數(shù)。

除了上述對(duì)bio請(qǐng)求的簡單處理,bio層最有意思的兩個(gè)功能就是:避免遞歸調(diào)用(recursion avoidance)和隊(duì)列激活(queue plugging)。

避免遞歸(recursion avoidance)

在存儲(chǔ)方案里,經(jīng)常用到"md" [mutiple device] (軟RAID就是md的一個(gè)實(shí)例)和"dm" [device mapper] (用于multipath和LVM2)這兩種虛擬設(shè)備,也常叫做棧式設(shè)備,由多個(gè)塊設(shè)備按樹的形式組織起來,它們會(huì)沿著設(shè)備樹往下一層一層對(duì)bio請(qǐng)求作修改和傳遞。如果采用遞歸的簡單的實(shí)現(xiàn),在設(shè)備樹很深的情況下,會(huì)占用大量的內(nèi)核棧空間。很久以前 (Linux 2.6.22),這個(gè)問題時(shí)不時(shí)會(huì)發(fā)生,在使用一些本身就因遞歸調(diào)用占用大量內(nèi)核棧空間的文件系統(tǒng)時(shí),情況更加糟糕。

為了避免遞歸,generic_make_request()會(huì)進(jìn)行檢測,如果發(fā)現(xiàn)遞歸,就不會(huì)把bio請(qǐng)求發(fā)送到下一層設(shè)備上。這種情況下,generic_make_request()會(huì)把bio請(qǐng)求放到進(jìn)程內(nèi)部的一個(gè)隊(duì)列上(currect->bio_list, struct task_struct的一個(gè)域), 等到上一次的bio請(qǐng)求處理完以后,然后再提交這一層的請(qǐng)求。由于generic_make_request()不會(huì)阻塞以等待bio處理完成,即使延遲一會(huì)再處理請(qǐng)求都是沒問題的。

通常,這個(gè)避免遞歸的方法都工作得很完美,但有時(shí)候可能發(fā)生死鎖。理解死鎖如何發(fā)生的關(guān)鍵就是上文我們對(duì)bio提交方式的觀察: 當(dāng)遞歸發(fā)生時(shí),bio要排隊(duì)等待之前已經(jīng)提交的bio處理完成。如果要等的bio一直在current->bio_list隊(duì)列上而得不到處理,它就會(huì)一直等下去。

引起bio互相等待而產(chǎn)生死鎖的原因,不太容易發(fā)現(xiàn),通常都是在測試中發(fā)現(xiàn)的,而不是分析代碼發(fā)現(xiàn)的。以bio拆分 (bio split)為例,當(dāng)一個(gè)bio的目標(biāo)設(shè)備在大小或?qū)R上有限制時(shí),make_request_fn()可能會(huì)把bio拆成兩部分,然后再分別處理。bio層提供了兩個(gè)函數(shù)(bio_split()和bio_chain()),使得bio拆分很容易,但是bio拆分需要給第二個(gè)bio結(jié)構(gòu)體分配空間。在塊層代碼里分配內(nèi)存要特別小心,尤其當(dāng)內(nèi)存緊張時(shí),Linux在回收內(nèi)存時(shí),需要把臟頁通過塊層寫出去。如果在內(nèi)存寫出的時(shí)候,又需要分配內(nèi)存,那就麻煩了。一個(gè)標(biāo)準(zhǔn)的機(jī)制就是使用mempool,為一個(gè)某種關(guān)鍵目的預(yù)留一些內(nèi)存。從mempool分配內(nèi)存需要等待其它mempool的使用者歸還一些內(nèi)存,而不用等待整個(gè)內(nèi)存回收算法完成。當(dāng)使用mempool分配bio內(nèi)存時(shí),這種等待可能會(huì)導(dǎo)致generic_make_request()死鎖。

社區(qū)已經(jīng)有多次嘗試提供一個(gè)簡單的方式來避免死鎖。一個(gè)是引入了"bioset" 進(jìn)程,你可以用ps命令在電腦上查看。這個(gè)機(jī)制主要關(guān)注的就是解決上面描述的死鎖問題,為每一個(gè)分配bio的"mempool"分配一個(gè)"rescuer"線程。如果發(fā)現(xiàn)bio分配不出來,所有在currect->bio_list的bio就會(huì)被取下來,交個(gè)相應(yīng)的bioset線程來處理。這個(gè)方法相當(dāng)復(fù)雜,導(dǎo)致創(chuàng)建了很多bioset線程,但是大多時(shí)候派不上用場,只是為了解決一個(gè)特殊的死鎖情況,代價(jià)太高了。通常,死鎖跟bio拆分有關(guān)系,但是它們不總是要等待mempool分配。[最后這句話,有些突兀]

最新的內(nèi)核通常不會(huì)創(chuàng)建bioset線程了,而只是在幾種個(gè)別情況下才會(huì)創(chuàng)建。Linux 4.11內(nèi)核,引入了另一個(gè)解決方案,對(duì)generic_make_request()做了改動(dòng),好處是更通用,代價(jià)小,但是卻對(duì)驅(qū)動(dòng)程序提出了一點(diǎn)要求。主要的要求是在發(fā)生bio拆分時(shí),其中一個(gè)bio要直接提交給generic_make_request()來安排最合適的時(shí)間處理,另一個(gè)bio可以用任何合適的方式處理,這樣generic_make_request()就有了更強(qiáng)的控制力。 根據(jù)bio在提交時(shí)在設(shè)備棧中的深度,對(duì)bio進(jìn)行排序后,總是先處理更低層設(shè)備的bio, 再處理較高層設(shè)備的bio。這個(gè)簡單的策略避免了所有惱人的死鎖問題。

塊隊(duì)列激活(queue plugging)

存儲(chǔ)設(shè)備處理單個(gè)IO請(qǐng)求的代價(jià)通常挺高的,因此提高處理效率的一個(gè)辦法就是把多個(gè)請(qǐng)求聚集起來,然后做一次批量提交。對(duì)于慢速設(shè)備來說,隊(duì)列上積攢的請(qǐng)求通常會(huì)多一些,那么做批處理的機(jī)會(huì)就多。但是,對(duì)于快速設(shè)備,或經(jīng)常處于空閑狀態(tài)的慢速設(shè)備來說,做批處理的機(jī)會(huì)就顯然少了很多。為了解決這個(gè)問題,Linux塊層提出了一個(gè)機(jī)制叫"plugging"。[plugging, 即堵上塞子,隊(duì)列就像水池,請(qǐng)求就像水,堵上塞子就可以蓄水了]

原來,plugging僅僅在隊(duì)列為空的時(shí)候才使用。在向一個(gè)空隊(duì)列提交請(qǐng)求前,這個(gè)隊(duì)列就會(huì)被“堵塞”上一會(huì)時(shí)間,好讓請(qǐng)求積蓄起來,暫時(shí)不往底層設(shè)備提交。文件系統(tǒng)提交的bio就會(huì)排起隊(duì)來,以便做批處理。文件系統(tǒng)可以主動(dòng)請(qǐng)求,或著定時(shí)器周期性超時(shí),來拔開塞子。我們預(yù)期的是在一定時(shí)間內(nèi)聚集一批請(qǐng)求,然后在一點(diǎn)延遲后就開始真正處理IO,而不是一直聚積特別多的請(qǐng)求。從Linux 2.6.30開始,有了一個(gè)新的plugging機(jī)制,把積蓄請(qǐng)求的對(duì)象,從面向每個(gè)設(shè)備,改成了面向每個(gè)進(jìn)程。這個(gè)改進(jìn)在多處理器上擴(kuò)張性很好。

當(dāng)文件系統(tǒng),或其它塊設(shè)備的使用者在提交請(qǐng)求時(shí),通常會(huì)在調(diào)用generic_make_request()前后加上blk_start_plug()和blk_finish_plug()。 blk_start_plug()會(huì)初始化一個(gè)struct blk_plug結(jié)構(gòu)體,讓current->plug指向它,這個(gè)結(jié)構(gòu)體里面包含一個(gè)請(qǐng)求列表(我們會(huì)在下一篇文章細(xì)說這個(gè))。因?yàn)檫@個(gè)請(qǐng)求列表是每個(gè)進(jìn)程就有一個(gè),所以在往列表里添加請(qǐng)求時(shí)不用上鎖。如果可以更高效率的處理請(qǐng)求,make_request_fn()就會(huì)把bio添加到這個(gè)列表上。

當(dāng)blk_finish_plug()被調(diào)用時(shí),或調(diào)用schedule()進(jìn)行進(jìn)程切換時(shí)(比如,等待mutex鎖,等待內(nèi)存分配等),保存在current->plug列表上的所有請(qǐng)求就要往底層設(shè)備提交,就是說進(jìn)程不能身負(fù)IO請(qǐng)求去睡覺。

調(diào)用schedule()進(jìn)行進(jìn)程切換時(shí),積蓄的bio會(huì)被全部處理,這個(gè)事實(shí)意為著bio處理的延遲只會(huì)發(fā)生在新的bio請(qǐng)求不斷產(chǎn)生期間。假如進(jìn)程因等待要進(jìn)入睡眠,那么積蓄起來的bio就會(huì)被立即處理。這樣可以避免出現(xiàn)循環(huán)等待的問題,試想一個(gè)進(jìn)程在等待一個(gè)bio請(qǐng)求處理完成而進(jìn)入睡眠,但是這個(gè)bio請(qǐng)求還在plug列表上并沒有下發(fā)給底層設(shè)備。

像這樣進(jìn)程級(jí)別的plugging機(jī)制,主要的好處一是相關(guān)性最強(qiáng)的bio會(huì)更容易聚集起來,以便批量處理,二是這樣很大程度上減少了隊(duì)列鎖的競爭。如果沒有進(jìn)程級(jí)別的plugging處理,那么每一個(gè)bio請(qǐng)求到來時(shí),都要進(jìn)行一次spinlock或原子操作。有了這樣的機(jī)制,每一個(gè)進(jìn)程就有一個(gè)bio列表,把進(jìn)程bio列表往設(shè)備隊(duì)列里合并時(shí),只需要上一次鎖就夠了。

bio層及以下(bio layer and below)

總之,bio層不是很復(fù)雜,它將IO請(qǐng)求以bio結(jié)構(gòu)體的方式直接傳遞給相應(yīng)的make_request_fn() [具體的實(shí)現(xiàn)有通用塊層的blk_queue_bio(), DM設(shè)備的dm_make_request(), MD設(shè)備的md_make_request()]。bio層實(shí)現(xiàn)了各種通用的函數(shù),來幫助設(shè)備驅(qū)動(dòng)層處理bio拆分,scheduling the sub-bios [不會(huì)翻譯這個(gè),意思應(yīng)該是安排拆分后的bio如何處理], "plugging"請(qǐng)求等。 bio層也會(huì)做一些簡單操作,比如更新/proc/vmstat中的pgpgin和pgpgout的計(jì)數(shù),然后把IO請(qǐng)求的大部分操作交給下一層處理 [request層]。

有時(shí)候,bio層的下一層就是最終的驅(qū)動(dòng),比如說DRBD(The Distributed Replicated Block Device)或 BRD (a RAM based block device). 更常見的下一層有MD和DM提供這種虛擬設(shè)備的中間層。不可或缺的一層,就是除bio層之外剩下的部分了,我稱之為"request 層",這將是我們?cè)谙乱黄懻摰?a href="http://srfitnesspt.com/v/tag/" target="_blank">話題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11161

    瀏覽量

    208460

原文標(biāo)題:塊層介紹 第一篇: bio層

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    4板手動(dòng)布線問題

    各位老師,一已用過一段時(shí)間的4板( 別人畫的),現(xiàn)想用手動(dòng)布線的方式做一些小的修改,但在布線時(shí),有一些新放置的過孔和焊盤,不知如何使它從頂層連接的底層?或頂層連接到電源?或連接到地線
    發(fā)表于 09-24 21:04

    AUTOSAR基礎(chǔ)軟件是由哪些部分組成

    基礎(chǔ)軟件主要是用于提供基礎(chǔ)軟件服務(wù),包括標(biāo)準(zhǔn)化的系統(tǒng)功能以及功能接口,并且由一系列的基礎(chǔ)服務(wù)軟件組成,包括系統(tǒng)服務(wù)、內(nèi)存服務(wù)、通信服務(wù)等。一、基礎(chǔ)軟件模塊按照類型可以分為驅(qū)動(dòng)模塊、接口模塊、處理模塊以及管理器。驅(qū)動(dòng)模塊:包含
    發(fā)表于 02-17 08:00

    EPA功能及用戶技術(shù)研究

    EPA功能及用戶技術(shù)研究 Research on EPA Functional Block and User Layer Technology
    發(fā)表于 03-17 09:14 ?16次下載

    交換技術(shù)解析

    交換技術(shù)解析 簡單地說,三交換技術(shù)就是:二交換技術(shù)+三轉(zhuǎn)發(fā)技術(shù)。它解決了局域網(wǎng)中網(wǎng)段劃分之
    發(fā)表于 08-01 11:59 ?629次閱讀

    深度剖析基于組成“request

    現(xiàn)在,"request"并存著兩種模型:單隊(duì)列(single-queue) 和 多隊(duì)列(multi-queue)。多隊(duì)列的出現(xiàn)也就是近幾年的事情,也許總有一天會(huì)完全取代單隊(duì)列的,但是目前來看兩者
    的頭像 發(fā)表于 02-03 16:29 ?4256次閱讀
    深度剖析基于<b class='flag-5'>塊</b><b class='flag-5'>層</b>的<b class='flag-5'>組成</b>“request<b class='flag-5'>層</b>”

    電纜外護(hù)的結(jié)構(gòu)組成是怎樣的,它的作用是什么

    外護(hù)是包覆在電纜護(hù)套(內(nèi)護(hù))外面的保護(hù)覆蓋層,主要起機(jī)械加強(qiáng)和防腐蝕的作用。常用電纜有內(nèi)護(hù)為金屬護(hù)的外護(hù)和內(nèi)護(hù)
    發(fā)表于 07-27 09:48 ?4570次閱讀

    pcb板各層畫什么?絲印 機(jī)械 阻焊 助焊 信號(hào) 鉆孔數(shù)據(jù)作用詳解

    pcb板在畫圖的時(shí)候大家都知道,電路板會(huì)有很多層,那么首先我們要知道都是PCB板子的哪些。通過對(duì)PCB的各個(gè)圖層的詳細(xì)解答,希望能夠?qū)Υ蠹疫M(jìn)一步了解一PCB的組成與設(shè)計(jì)有幫助。下面
    的頭像 發(fā)表于 08-17 11:25 ?2.1w次閱讀

    設(shè)備的數(shù)據(jù)結(jié)構(gòu) page/request和bio的關(guān)系

    主要內(nèi)容:從應(yīng)用程序發(fā)起一次IO行為,最終怎么到磁盤,以及在這個(gè)路徑上有什么trace的方法和 配置。每次應(yīng)用程序?qū)懘疟P,都是到pagecache 。三進(jìn)三出 講解 bio的一生,都是在pagecache以下。
    發(fā)表于 05-16 09:23 ?3903次閱讀
    <b class='flag-5'>塊</b>設(shè)備<b class='flag-5'>層</b>的數(shù)據(jù)結(jié)構(gòu) page/request和<b class='flag-5'>bio</b>的關(guān)系

    Linux架構(gòu)介紹 IO流程與IO調(diào)度器詳解

    之前一直跟大家聊文件系統(tǒng),文件系統(tǒng)提供一文件到物理的映射轉(zhuǎn)換。這邏輯可能非常復(fù)雜,依賴于文件系統(tǒng)的實(shí)現(xiàn)。今天則跟大家聊聊
    的頭像 發(fā)表于 05-16 12:12 ?2270次閱讀

    交換機(jī)的特點(diǎn)

    工作在網(wǎng)絡(luò)和傳輸之間:四交換機(jī)工作在OSI模型的第三和第四之間,可以支持TCP/IP協(xié)議的傳輸,既可以對(duì)IP報(bào)文頭進(jìn)行
    發(fā)表于 05-05 15:48 ?501次閱讀

    PCB阻焊與助焊的區(qū)別

    標(biāo)準(zhǔn)的印刷電路板 (PCB) 通常需要兩種不同類型的,即“罩 (mask)”。
    發(fā)表于 06-01 16:58 ?2604次閱讀
    PCB阻焊<b class='flag-5'>層</b>與助焊<b class='flag-5'>層</b>的區(qū)別

    技術(shù)資訊 I PCB 阻焊與助焊的區(qū)別

    本文要點(diǎn)PCB阻焊的基礎(chǔ)知識(shí)。了解焊膏在PCB上的作用。針對(duì)阻焊和助焊設(shè)置PCBCAD系統(tǒng)。一標(biāo)準(zhǔn)的印刷電路板(PCB)通常需要兩種不同類型的
    的頭像 發(fā)表于 07-18 17:34 ?2628次閱讀
    技術(shù)資訊 I PCB 阻焊<b class='flag-5'>層</b>與助焊<b class='flag-5'>層</b>的區(qū)別

    板如何設(shè)置板層

    板是一種常用于電子產(chǎn)品中的印制電路板(PCB),具有四個(gè)層次或?qū)用?。在設(shè)計(jì)四板時(shí),需要合理設(shè)置板層,以優(yōu)化電路性能和信號(hào)傳輸。本文將詳細(xì)介紹四板的板層設(shè)置方法。 四
    的頭像 發(fā)表于 12-21 11:26 ?1641次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)中池化的作用

    。其中,池化(Pooling Layer)作為CNN的重要組成部分,在降低模型復(fù)雜度、提高計(jì)算效率以及增強(qiáng)模型的不變性和魯棒性方面發(fā)揮著關(guān)鍵作用。本文將從多個(gè)方面深入探討池化的作用,力求全面
    的頭像 發(fā)表于 07-03 15:58 ?738次閱讀

    神經(jīng)網(wǎng)絡(luò)中的卷積、池化與全連接

    在深度學(xué)習(xí)中,卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN)是一種特別適用于處理圖像數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。它通過卷積、池化和全連接的組合,實(shí)現(xiàn)了對(duì)圖像特征的自動(dòng)提取和分類。本文將
    的頭像 發(fā)表于 07-11 14:18 ?3289次閱讀