English Site Vietnamese Site

Tối ưu hóa các thuật toán xử lý ảnh cho FPGA

dùng ngôn ngữ lập trình SA-C

Phần 1:

Tóm tắt:

Ngôn ngữ bậc cao SA-C được đưa vào ứng dụng xử lý ảnh. Ngôn ngữ SA-C là ngôn ngữ lập trình chuyển đổi C đơn. Nó cho phép biên dịch tối ưu với mục đích định dạng lại hệ thống. Các lớp trung gian DDCF, DFG và AHA, được sử dụng để tối ưu hóa và chuyển đổi tạo ra mã.

1.Giới thiệu:

FPGA là một thiết bị được lập trình chủ yếu với ngôn ngữ diễn tả phần cứng VHDL. Các nhà lập trình thường không được đào tạo về ngôn ngữ này và thường sử dụng ngôn ngữ bậc cao.

Đề án Cameron đã tạo ra một ngôn ngữ thuật toán bậc cao, có tên là SA-C, với mục đích riêng biệt là ứng dụng xử lý ảnh và biên dịch chúng tạo mã cho thiết bị FPGA.

Mục đích thiết kế của SA-C là một ngôn ngữ đưa vào ứng dụng trong xử lý ảnh (IP) và cho phép biên dịch liền mạch cho đinh dạng phần cứng. Ứng dụng IP được hỗ trợ bởi các vòng lặp dữ liệu song song với cấu trúc truy cập các mảng nhiều chiều vuông góc.

2.Ngôn ngữ SA-C: C giới hạn.

SA-C là một biến thể của ngôn ngữ lập trình C, nó có thể trực tiếp và trực quan ánh xạ tới các mạch điện kể cả FPGA. Một ngôn ngữ mới là cần thiết bởi vì C thừa nhận là sự tương ứng 1 – 1 giữa các biến và các vị trí trong bộ nhớ và kết quả là người lập trình chỉ có thể lấy địa chỉ của bất kỳ biến nào và các con trỏ dải tham khảo rõ ràng. Quan trọng hơn là SA-C là ngôn ngữ chuyển đổi đơn, dẫn đến giá trị của biến chỉ có thể được đặt duy nhất một lần. Như trước , đó là nguyên nhân các biến trong SA-C chuyển đổi thành các dây tương ứng và các dây điện có thể điều khiển bới duy nhất một nguồn. Ta có thể so sánh, trong C một biến là một vị trí trong bộ nhớ, nó có thể được đặt hay xóa trong xuốt quá trình của một thuật toán.

Ngôn ngữ C ngoài ra cũng thừa nhận chương trình C là công cụ với kiểu máy tính Von Neuman gọi ngăn xếp và kết quả là các hàm được trả về với mỗi lệnh gọi khác nhau. Điều đó không thể định rõ một vị trí trong một mạch điện, chúng phải trở thành một bộ phận có kích thước cố định của phần cứng. Vì thế SA-C cấm sự trả về của hàm gọi.

3.Ngôn ngữ SA-C: C mở rộng.

Ta đã thấy C bị giới hạn như thế nào, chúng tôi cần phải thêm một số đặc tính mới để bù đắp những hạn chế và để khai thác các đặc tính riêng của FPGA mà không có ở các bộ vi xử lý truyền thống. Hầu như sự mở rộng là thêm vào các ứng dụng xử lý tín hiệu và hình ảnh có thể. Thông qua rất nhiều ứng dụng khác nhau sẽ cho ta thấy lợi ích của SA-C đem lại là tuyệt với.

Xử lý tín hiệu và hình ảnh có một phần chung rất quan trong là sử dụng các con trỏ dữ liệu cho các mảng dữ liệu cực lớn. SA-C xóa bỏ các con trỏ được sử dụng đó bằng cách thêm các mảng đa chiều thực, bao gồm các mảng động. Ví dụ, Int32 arr[:,100] là khai báo một mảng 2 chiều với cột cố định là 100 và số dòng là tùy biến. SA-C cũng đưa vào vòng lặp song song , kỹ thuật này là rất chặt chẽ.

SA-C cũng khai thác tính mềm dẻo của FPGA bằng cách giới thiệu các biến với kiểu dữ liệu chính xác đến từng bít. Các số nguyên trong C bị giới hạn dạng Short, dạng tiêu chuẩn hay dạng Long, SA-C người lập trình có thể định rõ độ rộng của các biến theo các bít. Ví dụ, int32 được khai báo là số nguyên 32 bít truyền thống. Chúng ta cũng có thể viết int12 hay uint6 (số nguyên không dấu). SA-C cũng giới thiệu kiểu dữ liệu dấu phẩy cố định, cho phép người lập trình tránh xây dựng các mạch bị rắc rối với các phép tính dấu phẩy động bất kì khi nào có thể.

Kết luận, SA-C để bù lại sự phiền phức hạn chế bằng cách cho phép các tên biến có thể sử dung lại, và bằng cách chuyển rất nhiều các khai báo, câu lệnh của C vào thẳng các biểu thức. Các biến mới có thể được khai báo ở bất kỳ điểm nào trong chương trình của SA-C, và các biến phải được gán giá trị ban đầu khi chúng được khai báo. Để ngăn chăn sự gia tăng của các tên biến, bằng cách nào đó, SA-C có thể sử dụng lại các tên biến đã sử dụng trước đó. Khi một biến mới được khai báo với tên giống với biến trước đó, các biến trước đó sẽ bị ra ngoài phạm vi. Kết quả là, câu lệnh int12 x = x + 1; hoàn toàn hợp lý trong SA-C. Nó đơn giản là khai báo một biến mới x thay thế biến cũ x ( biến mới và cũ có thể hoặc không thể có cùng kiểu dữ liệu giống nhau)

4.Ví dụ về ngôn ngữ lập trình SA-C

Thực hiện xử lý ảnh kinh điên là tính toán biên độ của xườn ảnh sử dụng mặt nạ xườn theo trục dọc và trục ngang của ảnh. Ở đây là ví dụ về mặt nạ xườn Prewitt. Thuật toán cơ bản là: đầu tiên ta sử dụng thuật toán tích chập (convolution) ảnh với mặt nạ xườn trục dọc và trục ngang của ảnh, để tạo ra ảnh là ảnh xươn của ảnh gốc đáp ứng theo trục X và Y. Sau đó với mỗi điểm ảnh sẽ được tính là căn bậc 2 của tổng bình phương của 2 xườn ảnh trục X và Y. Kết quả là biên độ của xườn ảnh.

Trong SA-C , code sẽ được viết như sau:

//-----------------------------------------------------------//

int16[:,:] main (uint8 Image[:,:]) {

int16 H[3,3] = { { -1, -1, -1}, { 0, 0, 0}, { 1, 1, 1} };

int16 V[3,3] = { { -1, 0, 1}, { -1, 0, 1}, { -1, 0, 1} };

int16 M[:,:] = for window W[3,3] in Image

{

int16 dfdy, int16 dfdx= for h in H dot w in W dot v in V return( sum(h*w), sum(v*w) );

int16 magnitude = sqrt(dfdy*dfdy+dfdx*dfdx);

}

return( array(magnitude) ); }

return(M);

//-----------------------------------------------------------//

Vòng lặp bên trong được tính toán với cửa sổ 3x3 trong ảnh gốc. Điểm ảnh được tạo ra của cửa sổ với 2 mặt nạ xườn thực hiện phép tích chập.Phần code còn lại là tính toán biên độ xườn.

Thông qua đoạn mã cơ bản này cho xử lý ảnh,cho thấy nó rất quan trọng cho hệ thống xử lý song song. Các tích chập là các toán hạng xử lý dữ liệu song song kinh điển. Để thực hiện tối ưu hoá, biên dịch SA-C đã phải song song hoá các tích chập, mặc dù vẫn phải xử lý dạng đường ống (pipeline) với phép căn.

 

 

Ks: Nguyễn Văn Tiến

Email:herrtien@yahoo.com

còn tiếp . . .