http://www.oschina.net/question/583160_66329
void send_duff(char *to, char *from, int count) { int n = (count + 7) / 8; switch(count % 8) { case 0: do { *to++ = *from++; case 7: *to++ = *from++; case 6: *to++ = *from++; case 5: *to++ = *from++; case 4: *to++ = *from++; case 3: *to++ = *from++; case 2: *to++ = *from++; case 1: *to++ = *from++; } while(--n > 0); } }
1、我們希望不通過一個char ,一個char的傳遞。儘可能利用已有可控的帶寬。例如64位系統,我們就用64位傳遞。128位系統,就用128傳遞,當然這個和數據存儲位置也有關係。有的系統,外部MEM到片上是32位的,而片內L2到TCM是64位的。而TCM到寄存器是128位的。同時你是 C語言設計程序,還是設計DMA等總線控制器的一部分也不一樣。但基本精神不變,就是最大化的利用可控的軟硬件資源。落到C程序上,就是儘可能使用編譯器能支持的大位寬數據類型。
2、由於函數接口要求,對大位寬,例如64位或32位,沒有任何約束,包括起始地址邊界對齊問題和傳輸量的問題。因此需要分別對待。
3、首先需要關注傳輸量的問題。
4、其次關注起始地址偏移量不同的問題。
5、實際在循環中反覆的,存在一個位移的事情,例如一次可傳輸64位,則需要兩組64位數據,根據源地址,和目標地址偏移量的差值做適當位移,向左向右,需要根據實際偏移量哪個大,還有計算機的大數在前還是小數在前的情況,實際確定。
基本思想就是這樣,不用擔心數據COPY中存在移位等計算。計算機有pipeline的,數據預讀和存儲與這些計算都是可以併發操作的。所以整體性能遠比char 一個個傳的快。雖然char一個個傳,如上面代碼那樣,看似乾淨,但落到實際系統執行時,也還是需要依次等待內部總線可利用。除非編譯器自動識別,產生了DMA的機理操作。貌似除了特定書寫規範的代碼,按照編譯器的要求來書寫,否則編譯器無法實現這種動態識別。