2010-09-09 26 views
5

dự án xử lý hình ảnh của tôi hoạt động với hình ảnh thang độ xám. Tôi có nền tảng bộ vi xử lý ARM Cortex-A8. Tôi muốn sử dụng NEON.Tải 8 bit uint8_t thành uint32_t?

Tôi có hình ảnh thang độ xám (xem ví dụ bên dưới) và trong alogorithm của tôi, tôi chỉ phải thêm các cột.

Làm thế nào tôi có thể tải Bốn 8-bit điểm ảnh đánh giá cao song song, đó là uint8_t, như Bốn uint32_t thành một trong những thanh ghi 128-bit NEON? Tôi phải sử dụng cái gì để làm điều này?

Ý tôi là:

alt text

tôi phải load nó dưới dạng 32 bit bởi vì nếu bạn nhìn một cách cẩn thận, lúc này tôi làm 255 + 255 là 512, mà không thể được tổ chức tại một 8-bit ghi danh.

ví dụ:

255 255 255 255 ......... (640 pixels) 
255 255 255 255 
255 255 255 255 
255 255 255 255 
. 
. 
. 
. 
. 
(480 pixels) 
+2

255 + 255 = 510. – kennytm

Trả lời

11

Tôi sẽ khuyên bạn nên dành một chút thời gian để hiểu cách hoạt động của SIMD trên ARM. Xem xét:

Hãy xem tại địa chỉ:

  1. http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/
  2. http://blogs.arm.com/software-enablement/196-coding-for-neon-part-2-dealing-with-leftovers/
  3. http://blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multiplication/
  4. http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

để giúp bạn bắt đầu. Sau đó, bạn có thể triển khai mã SIMD của mình bằng cách sử dụng bộ lắp ghép nội tuyến hoặc nội tại ARM tương ứng được đề xuất bởi domen.

3

Nếu bạn cần tổng hợp tối đa 480 giá trị 8 bit thì bạn sẽ cần 17 bit lưu trữ trung gian về mặt kỹ thuật. Tuy nhiên, nếu bạn thực hiện việc bổ sung trong hai giai đoạn, tức là, hàng đầu 240 sau đó dưới 240 hàng, bạn có thể làm điều đó trong mỗi 16-bit. Sau đó, bạn có thể thêm kết quả từ hai nửa để có được câu trả lời cuối cùng.

Có thực sự là hướng dẫn NEON phù hợp với thuật toán của bạn được gọi là vaddw. Nó sẽ thêm một vec tơ dword vào một vec tơ qword, với vectơ có chứa các phần tử lớn gấp hai lần so với trước đây. Trong trường hợp của bạn, vaddw.u8 có thể được sử dụng để thêm 8 pixel đến 8 bộ tích lũy 16 bit. Sau đó, vaddw.u16 có thể được sử dụng để thêm hai bộ 8 bộ tích lũy 16 bit vào một bộ 8 bộ 32 bit - lưu ý rằng bạn phải sử dụng lệnh hai lần để lấy cả hai nửa.

Nếu cần, bạn cũng có thể chuyển đổi giá trị về 16 bit hoặc 8 bit bằng cách sử dụng vmovn hoặc vqmovn.

2

Không có hướng dẫn nào có thể tải giá trị 4 bit của bạn vào 4 thanh ghi 32 bit.

bạn phải tải chúng và sau đó sử dụng vshl hai lần. vì neon không thể sử dụng 32 thanh ghi bạn sẽ phải làm việc trên 8 pixel (và không 4)

Bạn chỉ có thể sử dụng thanh ghi 16bits. nó phải là đủ ...

0

Tải 4 byte bằng cách sử dụng hướng dẫn tải một làn đường (vld1 <register>[<lane>], [<address]) vào thanh ghi q, sau đó sử dụng hai hướng dẫn di chuyển dài (vmovl) để quảng bá chúng trước 16 và sau đó đến 32 bit. Kết quả sẽ được một cái gì đó tương tự (trong GNU cú pháp)

vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk>) 
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>) 
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>) 

Nếu bạn có thể đảm bảo rằng <address> là 4-byte aligned, sau đó viết [<address>: 32] thay vì trong hướng dẫn tải, để tiết kiệm một hoặc hai chu kỳ. Nếu bạn làm điều đó và địa chỉ không được căn chỉnh, bạn sẽ gặp lỗi.

Um, tôi mới nhận ra rằng bạn muốn sử dụng nội tại, không phải lắp ráp, vì vậy đây là điều tương tự với bản chất.

uint32x4_t v8; // Will actually hold 4 uint8_t 
v8 = vld1_lane_u32(ptr, v8, 0); 
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8))); 
const uint32x4_t v32 = vmovl_u16(v16); 
Các vấn đề liên quan