2008年11月13日 星期四

Multicore Programming:DMA Address alignment

以下是寫給學弟的程式,了解什麼是Alignment,本來要直接貼上code,
不過Syntax Highlight的使用方式有點麻煩,還是作罷。
此篇應該也能當作日後寫書的一個小小範例。

本程式最主要說明在Multi-Core Programming時,無論是SPE要抓去External Meomory,或是去抓取其他SPE在Local Store的資料,都需要以DMA的方式去抓取。
使用API mfc_put 或 mfc_get 需要注意Alignment的問題;例如現在想要做mfc_put,想要送過去的資料、要送過去的位址都必須是16-Byte Alignment。
但我們常常使用陣列來當做我們的儲存資料,如果是以integer 4個byte來傳送,每一次間隔不足16byte,又需要一個一個去傳送與接受會造成錯誤。
簡單地解決方式以struct構成一個16Byte的單位,但此方法較容易浪費記憶體。
以下程式說明了__attribute__ ((aligned (16)))使用方法,比較使用前後的差別。

程式在此

// Author : Jung-Yin, Chine @ SCREAM LAB
// Date : 2008/11/13


  1. #include <stdio.h>
  2. #include <stdint.h>
  3. typedef struct _ELEMENT{
  4. int a;
  5. uint8_t pad[16-sizeof(int)];
  6. }ELEMENT;
  7. ELEMENT a[10] __attribute__ ((aligned (16)));
  8. int b[10] __attribute__ ((aligned (16)));
  9. int c[10];
  10. int main()
  11. {
  12. int ival __attribute__ ((aligned (16)));
  13. int ival2 = 0;
  14. // variable alignment
  15. printf("align &ival addr %d mod16: %d\n",&ival,((unsigned int)&ival)%16);
  16. printf("not_align &ival2 addr %d mod16: %d\n",&ival2,((unsigned int)&ival2)%16);
  17. // ARRAY alignment
  18. printf("align &array addr %d mod16: %d\n",b,((unsigned int)b)%16);
  19. printf("not_align &array addr %d mod16: %d\n",c,((unsigned int)c)%16);
  20. // ARRAY ELEMENT
  21. printf("align &array[1] addr %d mod16: %d\n",&b[1],((unsigned int)&b)%16);
  22. printf("not_align &array[1] addr %d mod16: %d\n",&c[1],((unsigned int)&c)%16);
  23. // compare
  24. printf("align &array addr %d mod16: %d\n",a,((unsigned int)a)%16);
  25. printf("align &array addr %d mod16: %d\n",b,((unsigned int)b)%16);
  26. // ARRAY ELEMENT
  27. printf("align element &array[1] addr %d mod16: %d\n",&a[1],((unsigned int)&a[1])%16);
  28. printf("not align element &array[1] addr %d mod16: %d\n",&b[1],((unsigned int)&b[1])%16);
  29. return 0;
  30. }

13 則留言:

Zhong-Ho Chen 提到...

沒圖沒真相!

逼逼逼 提到...

補上真相

感謝巴肥特提供的Syntax Hightlignting
我找的都沒那麼好用,不然就是沒辦法貼在google blog

http://tools.devshed.com/webmaster-tools/syntax-highlighting/

逼逼逼 提到...

可惜沒辦法縮排,不過已經很好用了。
而且因為我們blog的版面是旁邊還能回覆,所以程式沒辦法寫太長

Zhong-Ho Chen 提到...

是字?是圖? 傻傻分不清楚
不過我也覺的寬度好小 @@

87showmin 提到...

寬度是可以改的,有興趣改網頁tamplate的人可以跟我要Scream Lab帳號去改。
gay中之前也有研究過怎麼在blog貼code,我覺得像JavaWorld那種就很棒,只是卡欄寬真的是個大問題。
http://www.javaworld.com.tw/jute/post/view?bid=5&id=244175&sty=1&tpg=1&age=0

SCREAMLab 提到...

改blog寬度不是辦法, 因為再寬都可能不夠用, 有更好的方法嗎?

要不然只好貼連結了.

SCREAMLab 提到...

像這種alignment的問題很多地方都會碰到. 可以做一個考慮周詳的工具讓user不必自己take care這個問題嗎?

逼逼逼 提到...

嗯...需要想想。
簡單的做法是做個小工具檢查User有沒有將要DMA的data address做alignment,data的大小是不是16byte的倍數。
因為不是每個變數都需要做alignment與pad,只有需要DMA的變數才要。

Zhong-Ho Chen 提到...

align的問題寫MMX或SSE的Assembly的時後也會碰到

這個問題算是進階的Compiler
因為有Type Convert和Runtime的問題
不可能用有效率的Static的方法解掉
VC的做法是執行的時後跟你講align有錯
PS3工具好像比較弱一點~ 不過我相信他們之後會自己改

第一次碰到align問題可能會很困擾很久
但是弄清楚之後就覺的沒什麼了

逼逼逼 提到...

在SPE compiler會自動幫你做address alignment的,我自己將它轉成assembly code看到的 :p
不過PPE的compiler就沒有了(因為不是必需品),還是得用一下compiler attribute。
但不論是PPE或SPE compiler,都需要注意pad的問題 :)

Zhong-Ho Chen 提到...

key point在於下面這段code
void foo(int* dat)
dma(dat, 1024);

compile的時後不知道dat這個指標有沒有align...

一般人可能會覺的 int 就一定有align?
但是看一下, 下面這段code...
char packet[4096];
foo((int*)(packet+3));

所以我說這個進階compiler的問題

匿名 提到...

Aaa說得對, 我以前在教Intel MMX指令的時候就特別注意提醒同學這點, 我以前在用多顆TI-C4X DSP的時候是第一次吃過alignment的苦頭, debug了很多天都不知道原因.

不做一個工具也可以, 出書的時候寫一下就ok.

SCREAMLab 提到...

bbb:

你的present資料都不更新嗎?