最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

stm32mp157 linux開發(fā)板ARM裸機(jī)開發(fā)教程4:Cortex-A7 內(nèi)核存儲(chǔ)系統(tǒng)與流水線(連載中)

2023-04-11 14:44 作者:華清遠(yuǎn)見研發(fā)中心  | 我要投稿

前言:

目前針對ARM Cortex-A7裸機(jī)開發(fā)文檔及視頻進(jìn)行了二次升級(jí)持續(xù)更新中,使其內(nèi)容更加豐富,講解更加細(xì)致,全文所使用的開發(fā)平臺(tái)均為華清遠(yuǎn)見FS-MP1A開發(fā)板(STM32MP157開發(fā)板)

針對對FS-MP1A開發(fā)板,除了Cortex-A7裸機(jī)開發(fā)篇外,還包括其他多系列教程,包括Cortex-M4開發(fā)篇、FreeRTOS篇、Linux基礎(chǔ)及應(yīng)用開發(fā)篇、Linux系統(tǒng)移植篇、Linux驅(qū)動(dòng)開發(fā)篇、硬件設(shè)計(jì)篇、人工智能機(jī)器視覺篇、Qt應(yīng)用編程篇、Qt綜合項(xiàng)目實(shí)戰(zhàn)篇等。除此之外計(jì)劃針對Linux系統(tǒng)移植篇、Linux驅(qū)動(dòng)開發(fā)篇均會(huì)進(jìn)行文檔及視頻的二次升級(jí)更新敬請關(guān)注!

開發(fā)板更多資料可關(guān)注"華清遠(yuǎn)見在線實(shí)驗(yàn)室"(微信號(hào):hqyjlab)領(lǐng)取~~?

Cortex-A7 內(nèi)核存儲(chǔ)系統(tǒng)與流水線

存儲(chǔ)系統(tǒng)概述

ARM 的存儲(chǔ)器系統(tǒng)是由多級(jí)構(gòu)成的,可以分為內(nèi)核級(jí)、芯片級(jí)、板卡級(jí)、外設(shè)級(jí),如下圖所示


每級(jí)都有特定的存儲(chǔ)介質(zhì),下面對比各級(jí)系統(tǒng)中特定存儲(chǔ)介質(zhì)的存儲(chǔ)性能。

? 內(nèi)核級(jí)的寄存器。處理器寄存器組可看做是存儲(chǔ)器層次的頂層。這些寄存器被集成在處理器內(nèi)核中,在系統(tǒng)中提供最快的存儲(chǔ)器訪問。典型的 ARM 處理器有多個(gè) 32 位寄存器,其訪問時(shí)間為ns 量級(jí)。

? 片級(jí)的緊耦合存儲(chǔ)器(TCM,部分處理器有)是為彌補(bǔ) Cache 訪問的不確定性增加的存儲(chǔ)器。TCM 是一種快速 SDRAM,它緊挨內(nèi)核,并且保證取指和數(shù)據(jù)操作的時(shí)鐘周期數(shù),這一點(diǎn)對一些要求確定行為的實(shí)時(shí)算法是很重要的。TCM 位于存儲(chǔ)器地址映射中,可作為快速存儲(chǔ)器來訪問。

? 芯片級(jí)的片上 Cache 存儲(chǔ)器的容量在 8KB~32KB 之間,訪問時(shí)間大約為 10ns 級(jí)別。高性能的

ARM 結(jié)構(gòu)中,可能存在第二級(jí)片外 Cache,容量為幾百 KB,訪問時(shí)間為幾十 ns 級(jí)別。

? 板卡級(jí)的 DRAM。主存儲(chǔ)器可能是幾 MB 到幾十 MB 的動(dòng)態(tài)存儲(chǔ)器,訪問時(shí)間大約為100ns。

? 外設(shè)級(jí)的后援存儲(chǔ)器,通常是硬盤,可能從幾百 MB 到幾十個(gè) GB,訪問時(shí)間約為幾十 ms 級(jí)別。

處理器核內(nèi)部的存儲(chǔ)管理單元主要包含有:Cache、MMU、Write Buffer(寫緩存)等部分,以及可以控制相關(guān)存儲(chǔ)單元的協(xié)處理 CP15。下圖是一個(gè)簡易結(jié)構(gòu)圖。

?Cortex-A7 內(nèi)核存儲(chǔ)

上個(gè)章節(jié)已經(jīng)了解了 Cortex-A7 內(nèi)核的寄存器的情況,本章節(jié)將整體了解 STM32MP1 的 Cortex-A7 內(nèi)核的存儲(chǔ)結(jié)構(gòu),如下圖所示。

可以看出 Cortex-A7 內(nèi)核有兩級(jí) Cache,而且是哈佛結(jié)構(gòu)的 Cache(早期 ARM7 為馮洛伊曼結(jié)構(gòu)),指令和數(shù)據(jù)可以同時(shí)和 Icache、Dache 交互(這也是 5 級(jí)以上流水線的要求,在流水線章節(jié)會(huì)講解)??梢悦枋鰹槿缦陆Y(jié)構(gòu):

在創(chuàng)建多任務(wù)嵌入式系統(tǒng)時(shí),最好用一個(gè)簡單的方式來編寫、裝載及運(yùn)行各自獨(dú)立的任務(wù)。目前大多數(shù)的嵌入式系統(tǒng)不再使用自己定制的控制系統(tǒng),而使用操作系統(tǒng)來簡化這個(gè)過程。較高級(jí)的操作系統(tǒng)采用基于硬件的存儲(chǔ)管理單元(MMU)來實(shí)現(xiàn)上述操作。

MMU 提供的一個(gè)關(guān)鍵服務(wù)是使各個(gè)任務(wù)作為各自獨(dú)立的程序在自己的私有存儲(chǔ)空間中運(yùn)行。在帶 MMU的操作系統(tǒng)控制下,運(yùn)行的任務(wù)無須知道其他與之無關(guān)的任務(wù)的存儲(chǔ)需求情況,這就簡化了各個(gè)任務(wù)的設(shè)計(jì)。

MMU 提供了一些資源以允許使用虛擬存儲(chǔ)器(將系統(tǒng)物理存儲(chǔ)器重新編址,可將其看成一個(gè)獨(dú)立于系統(tǒng)物理存儲(chǔ)器的存儲(chǔ)空間)。MMU 作為轉(zhuǎn)換器,將程序和數(shù)據(jù)的虛擬地址(編譯時(shí)的連接地址)轉(zhuǎn)換成實(shí)際的物理地址,即在物理主存中的地址。這個(gè)轉(zhuǎn)換過程允許運(yùn)行的多個(gè)程序使用相同的虛擬地址,而各自存儲(chǔ)在物理存儲(chǔ)器的不同位置。

這樣存儲(chǔ)器就有兩種類型的地址:虛擬地址和物理地址。虛擬地址由編譯器和連接器在定位程序時(shí)分配;物理地址用來訪問實(shí)際的主存硬件模塊(物理上程序存在的區(qū)域)。

MMU 的開啟指令:?

1 mrc p15, 0, r1, c1, c0, 0 //Read control register

2 orr r1, #0x1 //Set M bit

3 mcr p15, 0,r1,c1, c0,0 //Write control register and enable MMU

MMU 的關(guān)閉指令:?

1 mrc p15, 0, r1, c1, c0, 0 //Read control register

2 bic r1, r1, #0x1 //Clr M bit

3 mcr p15, 0,r1,c1, c0,0 //Write control register and enable MMU

高速緩沖存儲(chǔ)器(Cache)、寫緩存器(write buffer)

Cache 是一個(gè)容量小但存取速度非??斓拇鎯?chǔ)器,它保存最近用到的存儲(chǔ)器數(shù)據(jù)副本。對于程序員來說,Cache 是透明的。它自動(dòng)決定保存哪些數(shù)據(jù)、覆蓋哪些數(shù)據(jù)。現(xiàn)在 Cache 通常與處理器在同一芯片上實(shí)現(xiàn)。Cache 能夠發(fā)揮作用是因?yàn)槌绦蚓哂芯植啃?。所謂局部性就是指在任何特定的時(shí)間,處理器趨于對相同區(qū)域的數(shù)據(jù)(如堆棧)多次執(zhí)行相同的指令(如循環(huán))。

Cache 經(jīng)常與寫緩存器(write buffer)一起使用。寫緩存器是一個(gè)非常小的先進(jìn)先出(FIFO)存儲(chǔ)器,位于處理器核與主存之間。使用寫緩存的目的是,將處理器核和 Cache 從較慢的主存寫操作中解脫出來。當(dāng) CPU 向主存儲(chǔ)器做寫入操作時(shí),它先將數(shù)據(jù)寫入到寫緩存區(qū)中,由于寫緩存器的速度很高,這種寫入操作的速度也將很高。寫緩存區(qū)在 CPU 空閑時(shí),以較低的速度將數(shù)據(jù)寫入到主存儲(chǔ)器中相應(yīng)的位置。

通過引入 Cache 和寫緩存區(qū),存儲(chǔ)系統(tǒng)的性能得到了很大的提高,但同時(shí)也帶來了一些問題。例如,由于數(shù)據(jù)將存在于系統(tǒng)中不同的物理位置,可能造成數(shù)據(jù)的不一致性;由于寫緩存區(qū)的優(yōu)化作用,可能有些寫操作的執(zhí)行順序不是用戶期望的順序,從而造成操作錯(cuò)誤。所以在后續(xù)學(xué)習(xí)驅(qū)動(dòng)開發(fā)時(shí),要注意,針對外設(shè)硬件寄存器空間的 MMU 內(nèi)存管理,在頁表的 C、B 位設(shè)置權(quán)限,小心設(shè)置,一般選擇不支持 Cache、不支持 write buffer。注意:內(nèi)存管理是分段或頁面管理的,不同頁面的權(quán)限設(shè)置不一樣。

當(dāng)然可以可以整體開啟或關(guān)閉 Cache。

ICache 是在整體 Cache 打開后,可以單獨(dú)設(shè)置開關(guān),MMU 不開啟時(shí),也可以使用。

DCache 是依賴于 MMU,只有開啟 MMU 后,Dcache 才有效,并且受 MMU 控制。

指令 Cache 的打開和關(guān)閉,可以用通用寄存器和 CP15 協(xié)處理中的 C1 寄存器進(jìn)行交互,設(shè)置指令Cache 的開關(guān)。下圖為 C1 寄存器。

我們?nèi)匀辉趯?dǎo)入的 c_led 工程的 start.S 中增加這段代碼,調(diào)試,觀察現(xiàn)象(因?yàn)?r0 已經(jīng)被程序占用,可以使用 r1 寄存器)。?

1 /******Cache Test*******/

2 mrc p15,0,r1,c1,c0,0

3 orr r1, r1, #(1 << 2) // Set C bit 整體使能Cache

4 orr r1, r1, #(1 << 12) //Set I bit 使能ICache

5 mcr p15,0,r1,c1,c0,0

6 /******End Test******/

通過設(shè)置的斷點(diǎn),可以看到 r1 的值為 0x5187f,對應(yīng)的 C 位和 I 位為 1,說明 ICache 原本已經(jīng)是打開的,也就是說增加的代碼不影響原來的結(jié)果。接下來運(yùn)行程序,記住 FS-MP1A 開發(fā)板上的 Led 燈閃爍頻率。注意因?yàn)?M 位也為 1,說明

接下來測試關(guān)閉 ICache 對程序的影響。還是在剛剛的位置,增加關(guān)閉 ICache 的指令。

1 /******Cache Test*******/

2 mrc p15,0,r1,c1,c0,0

3 orr r1, r1, #(1 << 2) // Set C bit 整體使能Cache

4 orr r1, r1, #(1 << 12) //Set I bit 使能Cache

5 bic r1, r1, #(1 << 12)//關(guān)閉ICache

6 //bic r1, r1, #(1 << 2)//關(guān)閉Cache

7 mcr p15,0,r1,c1,c0,0

8 /******End Test******/

編譯執(zhí)行,可以觀察到關(guān)閉了 ICache 的代碼,點(diǎn)燈速度慢了很多。

流水線的概念與原理

處理器按照一系列步驟來執(zhí)行每一條指令,典型的步驟如下:

1、從存儲(chǔ)器讀取指令(fetch)。

2、譯碼以鑒別它屬于哪一條指令(decode)。

3、從指令中提取指令的操作數(shù)(這些操作數(shù)往往存在于寄存器 reg 中)。

4、將操作數(shù)進(jìn)行組合以得到結(jié)果或存儲(chǔ)器地址(ALU)。

5、如果需要,則訪問存儲(chǔ)器以存儲(chǔ)數(shù)據(jù)(mem)。

6、將結(jié)果寫回到寄存器堆(res)

并不是所有的指令都需要上述每一個(gè)步驟,但是,多數(shù)指令需要其中的多個(gè)步驟。這些步驟往往使用不同的硬件功能,如 ALU 可能只在第 4 步中用到。因此,如果一條指令不是在前一條指令結(jié)束之前就開始,那么在每一步驟內(nèi)處理器只有少部分的硬件在使用。

有一種方法可以明顯改善硬件資源的使用率和處理器的吞吐量,這就是在當(dāng)前一條指令結(jié)束之前就開始執(zhí)行下一條指令,即通常所說的流水線(Pipeline)技術(shù)。流水線是 RISC 處理器執(zhí)行指令時(shí)采用的機(jī)制。使用流水線,可在取下一條指令的同時(shí)譯碼和執(zhí)行其他指令,從而加快執(zhí)行的速度??梢园蚜魉€看做是汽車生產(chǎn)線,每個(gè)階段只完成專門的處理器任務(wù)。

采用上述操作順序,處理器可以這樣來組織:當(dāng)一條指令剛剛執(zhí)行完步驟(1)并轉(zhuǎn)向步驟(2)時(shí),下一條指令就開始執(zhí)行步驟(1)。從原理上說,這樣的流水線應(yīng)該比沒有重疊的指令執(zhí)行快 6 倍,但由于硬件結(jié)構(gòu)本身的一些限制,實(shí)際情況會(huì)比理想狀態(tài)差一些。

流水線的分類

3級(jí)流水線

到 ARM7 為止的 ARM 處理器使用簡單的 3 級(jí)流水線,它包括下列流水線級(jí)。

1、取指令(fetch):從寄存器裝載一條指令。

2、譯碼(decode):識(shí)別被執(zhí)行的指令,并為下一個(gè)周期準(zhǔn)備數(shù)據(jù)通路的控制信號(hào)。在這一級(jí),指令占有譯碼邏輯,不占用數(shù)據(jù)通路。

3、執(zhí)行(excute):處理指令并將結(jié)果寫回寄存器。

如下圖所示為:3 級(jí)流水線指令的執(zhí)行過程。

我們?nèi)匀辉趯?dǎo)入的 c_led 工程的 start.S 中增加下面的代碼,調(diào)試,觀察。

1 /****pipeline test begin****/

2 mov r1,pc

3 /****pipeline test end****/

運(yùn)行結(jié)果如下:

可以發(fā)現(xiàn),當(dāng)指令執(zhí)行完成后,R1 中的值是在執(zhí)行階段賦予的,即 R1=0xc20000a8 是執(zhí)行階段 PC 的值,而這條指令本身的地址=0xc20000a0。說明執(zhí)行階段的這條指令的地址=PC-8。(注:后文會(huì)有描述,雖然 A7 處理器是 8 級(jí)流水線,但也符合這個(gè)規(guī)則)

當(dāng)處理器執(zhí)行簡單的數(shù)據(jù)處理指令時(shí),流水線使得平均每個(gè)時(shí)鐘周期能完成 1 條指令。但 1 條指令需要 3 個(gè)時(shí)鐘周期來完成,因此,有 3 個(gè)時(shí)鐘周期的延時(shí)(latency),但吞吐率(throughput)是每個(gè)周期 1 條指令。下面的情況是三級(jí)流水線的最佳情況。

該例中用 6 個(gè)時(shí)鐘周期執(zhí)行了 6 條指令,所有的操作都在寄存器中(單周期執(zhí)行),指令周期數(shù)(CPI) = 1。

在三級(jí)流水線中,如果遇到 LDR、STR 命令,需要訪問內(nèi)存時(shí),如下圖所示:

該例中,用 6 周期執(zhí)行了 4 條指令,指令周期數(shù) (CPI) = 1.5。

5級(jí)流水線

所有的處理器都要滿足對高性能的要求,直到 ARM7 為止,在 ARM 核中使用的 3 級(jí)流水線的性價(jià)比是很高的。但是,為了得到更高的性能,需要重新考慮處理器的組織結(jié)構(gòu)。有兩種方法來提高性能。

提高時(shí)鐘頻率。時(shí)鐘頻率的提高,必然引起指令執(zhí)行周期的縮短,所以要求簡化流水線每一級(jí)的邏輯,流水線的級(jí)數(shù)就要增加。

減少每條指令的平均指令周期數(shù) CPI。這就要求重新考慮 3 級(jí)流水線 ARM 中多于 1 個(gè)流水線周期的實(shí)現(xiàn)方法,以便使其占有較少的周期,或者減少因指令相關(guān)造成的流水線停頓,也可以將兩者結(jié)合起來。

3 級(jí)流水線 ARM 核在每一個(gè)時(shí)鐘周期都訪問存儲(chǔ)器,或者取指令,或者傳輸數(shù)據(jù)。只是抓緊存儲(chǔ)器不用的幾個(gè)周期來改善系統(tǒng)性能,效果并不明顯。為了改善 CPI,存儲(chǔ)器系統(tǒng)必須在每個(gè)時(shí)鐘周期中給出多于一個(gè)的數(shù)據(jù)。方法是在每個(gè)時(shí)鐘周期從單個(gè)存儲(chǔ)器中給出多于 32 位數(shù)據(jù),或者為指令或數(shù)據(jù)分別設(shè)置存儲(chǔ)器。

基于以上原因,較高性能的 ARM 核使用了 5 級(jí)流水線,而且具有分開的指令和數(shù)據(jù)存儲(chǔ)器。把指令的執(zhí)行分割為 5 部分而不是 3 部分,進(jìn)而可以使用更高的時(shí)鐘頻率,分開的指令和數(shù)據(jù)存儲(chǔ)器使核的 CPI明顯減少。

在 ARM9TDMI 中使用了典型的 5 級(jí)流水線,5 級(jí)流水線包括下面的流水線級(jí)。

1、取指令(fetch):從存儲(chǔ)器中取出指令,并將其放入指令流水線。

2、譯碼(decode):指令被譯碼,從寄存器堆中讀取寄存器操作數(shù)。在寄存器堆中有 3 個(gè)操作數(shù)讀端口,因此,大多數(shù) ARM 指令能在 1 個(gè)周期內(nèi)讀取其操作數(shù)。

3、執(zhí)行(execute):將其中 1 個(gè)操作數(shù)移位,并在 ALU 中產(chǎn)生結(jié)果。如果指令是 Load 或 Store 指令,則在 ALU 中計(jì)算存儲(chǔ)器的地址。

4、緩沖/數(shù)據(jù)(buffer/data):如果需要?jiǎng)t訪問數(shù)據(jù)存儲(chǔ)器,否則 ALU 只是簡單地緩沖 1 個(gè)時(shí)鐘周期。

5、回寫(write-back):將指令的結(jié)果回寫到寄存器堆,包括任何從寄存器讀出的數(shù)據(jù)。

如下圖所示列出了 5 級(jí)流水線指令的執(zhí)行過程。

在程序執(zhí)行過程中,PC 值是基于 3 級(jí)流水線操作特性的。5 級(jí)流水線中提前 1 級(jí)來讀取指令操作數(shù),得到的值是不同的(PC+4 而不是 PC+8)。這里產(chǎn)生代碼不兼容是不容許的。但 5 級(jí)流水線 ARM 完全仿真 3 級(jí)流水線的行為。在取指級(jí)增加的 PC 值被直接送到譯碼級(jí)的寄存器,穿過兩級(jí)之間的流水線寄存器。下一條指令的 PC+4 等于當(dāng)前指令的 PC+8,因此,未使用額外的硬件便得到了正確的 R15。

8 級(jí)流水線

在 Cortex-A7 中有一條 8 級(jí)的流水線,但沒有找到相關(guān)的細(xì)節(jié)資料,這里只能簡單介紹一下。從經(jīng)典 ARM 系列到現(xiàn)在的 Cortex 系列,ARM 處理器的結(jié)構(gòu)在向復(fù)雜的階段發(fā)展,但沒改變的是 CPU 的取指指令和地址關(guān)系,不管是幾級(jí)流水線,都可以按照最初的 3 級(jí)流水線的操作特性來判斷其當(dāng)前的 PC 位置。這樣做主要還是為了軟件兼容性上的考慮,由此可以判斷的是,后面 ARM 所推出的處理核心都想滿足這一特點(diǎn),感興趣的讀者可以自行查閱相關(guān)資料。

影響流水線性能的因素

互鎖

在典型的程序處理過程中,經(jīng)常會(huì)遇到這樣的情形,即一條指令的結(jié)果被用做下一條指令的操作數(shù)。例如,有如下指令序列:

LDR R4,[R7]

ORR R8,R3,R4 ;在 5 級(jí)流水線上產(chǎn)生互鎖

從例子可以看出,流水線的操作產(chǎn)生中斷,因?yàn)榈?1 條指令的結(jié)果在第 2 條指令取數(shù)時(shí)還沒有產(chǎn)生。第 2 條指令必須停止,直到結(jié)果產(chǎn)生為止。本例中,用了 7 個(gè)時(shí)鐘周期執(zhí)行 6 條指令, CPI = 1.2 。

但如果將 ORR R8,R3,R4 和 AND R6,R3,R1 調(diào)換順序,則在不影響程序結(jié)果的情況下,得到了更好的流水線效果。大家以后學(xué)習(xí) Linux 內(nèi)核時(shí),會(huì)遇到內(nèi)存屏障的概念,有時(shí)就是為了防止編譯器做這種指令順序上的優(yōu)化。

本例中,用了 6 個(gè)時(shí)鐘周期執(zhí)行 6 條指令, CPI = 1。

跳轉(zhuǎn)指令

跳轉(zhuǎn)指令也會(huì)破壞流水線的行為,因?yàn)楹罄m(xù)指令的取指步驟受到跳轉(zhuǎn)目標(biāo)計(jì)算的影響,因而必須推遲。但是,當(dāng)跳轉(zhuǎn)指令被譯碼時(shí),在它被確認(rèn)是跳轉(zhuǎn)指令之前,后續(xù)的取指操作已經(jīng)發(fā)生。這樣一來,已經(jīng)被預(yù)取進(jìn)入流水線的指令不得不被丟棄。如果跳轉(zhuǎn)目標(biāo)的計(jì)算是在 ALU 階段完成的,那么在得到跳轉(zhuǎn)目標(biāo)之前已經(jīng)有兩條指令按原有指令流讀取。

顯然,只有當(dāng)所有指令都依照相似的步驟執(zhí)行時(shí),流水線的效率達(dá)到最高。如果處理器的指令非常復(fù)雜,每一條指令的行為都與下一條指令不同,那么就很難用流水線實(shí)現(xiàn)。

小結(jié)

Cache 和 MMU 部分,目前只做功能介紹,和簡單的測試實(shí)驗(yàn),大家目前需要理解它們的作用。等打好基礎(chǔ)后,可以繼續(xù)了解 Cache 內(nèi)部的結(jié)構(gòu),以及控制方法,比如:Cache 的覆蓋機(jī)制、鎖定機(jī)制。MMU 的一級(jí)頁表和二級(jí)頁表編寫,權(quán)限管理等。這些內(nèi)容對應(yīng)以后嵌入式 Linux 驅(qū)動(dòng)、內(nèi)核優(yōu)化、內(nèi)存管理的學(xué)習(xí)、實(shí)時(shí)性的優(yōu)化都很有意義。編寫驅(qū)動(dòng)時(shí)遇到的一些疑難問題也可能和這部分存儲(chǔ)系統(tǒng)有關(guān)系。

stm32mp157 linux開發(fā)板ARM裸機(jī)開發(fā)教程4:Cortex-A7 內(nèi)核存儲(chǔ)系統(tǒng)與流水線(連載中)的評論 (共 條)

分享到微博請遵守國家法律
册亨县| 偃师市| 保康县| 岚皋县| 仪陇县| 乌兰县| 长治县| 乌鲁木齐县| 十堰市| 都江堰市| 金塔县| 阿坝| 环江| 保定市| 乌鲁木齐市| 翁牛特旗| 黔东| 西峡县| 乌兰察布市| 彭泽县| 抚顺县| 岳普湖县| 茂名市| 桦甸市| 兴仁县| 股票| 将乐县| 西安市| 武胜县| 敦化市| 吴桥县| 东海县| 巴塘县| 二手房| 肇源县| 望谟县| 江油市| 同德县| 富阳市| 洪湖市| 连州市|