2009-12-22 19 views
5

Tôi đang lập trình, cho nền tảng C, một thư viện để thực hiện nhiều thứ khác nhau cho hình ảnh webcam. Tất cả các hoạt động là trên mỗi pixel và có khả năng song song cao - ví dụ như áp dụng các mặt nạ bit, nhân các giá trị màu theo các hằng số, vv Vì vậy, tôi nghĩ rằng tôi có thể đạt được hiệu năng bằng cách sử dụng nội tại SSE/SSE2.Xử lý pixel byte với nội dung SSE/SSE2 trong C

Tuy nhiên, tôi gặp sự cố về định dạng dữ liệu. Thư viện webcam của tôi cho tôi khung hình webcam dưới dạng con trỏ (void *) đối với bộ đệm chứa các pixel byte 24 hoặc 32 bit ở định dạng ABGR hoặc BGR. Tôi đã được đúc này để char * để ptr ++ vv cư xử một cách chính xác. Tuy nhiên, tất cả các hoạt động SSE/SSE2 đều mong đợi bốn số nguyên hoặc bốn số float, trong các kiểu dữ liệu __m128 hoặc __m64. Nếu tôi làm điều này (giả sử tôi đã đọc các giá trị màu từ bộ đệm vào ký tự r, g và b):

float pixel [] = {(float) r, (float) g, {float) b, 0,0f};

sau đó tải một mảng phao đầy đủ các hằng số

hằng float [] = {0,299, 0,587, 0,114, 0.0f};

cast cả con trỏ float để __m128, và sử dụng __mm_mul_ps nội tại để làm r * 0,299, g * 0,587 vv vv ... không có đạt được hiệu suất tổng thể bởi vì tất cả những thứ xung quanh shuffling chiếm rất nhiều thời gian!

Có ai có bất kỳ đề xuất nào về cách tôi có thể tải các giá trị pixel byte này một cách nhanh chóng và hiệu quả vào thanh ghi SSE để tôi thực sự có được hiệu suất hoạt động trên chúng không?

+2

Bạn cần phải thực hiện các hoạt động nổi-điểm? Ngoài ra còn có MMX, hoạt động trên các loại số nguyên. –

+0

Thật vậy. Nếu bạn đang làm việc trên các loại số nguyên, bạn nên sử dụng các hướng dẫn SIMD không tách rời, thay vì các chỉ lệnh dấu phẩy động. –

+0

tôi không cần phải làm bất cứ điều gì dấu chấm động, vì vậy bạn nói đúng, hướng dẫn nguyên MMX là hoàn toàn phù hợp. –

Trả lời

1

Nếu bạn sẵn sàng để sử dụng MMX ...

MMX cung cấp cho bạn một loạt các thanh ghi 64 bit có thể đối xử với nhau như đăng ký 8, giá trị 8-bit.

Giống như các giá trị 8 bit mà bạn đang làm việc.

Có mồi tốt here.

+1

đó không phải thực sự là gợi ý tốt nhất như MMX đang trở thành lỗi thời và có SSE2, thực hiện gần gấp đôi nhanh như MMX –

0

Đầu tiên, dữ liệu bạn đang sao chép từ (tôi đoán nó được trỏ đến bởi con trỏ void*) nên được sắp xếp bộ nhớ cho hiệu suất tối ưu - nếu không sao chép nó vào bộ đệm được liên kết bộ nhớ.

Thứ hai, bạn vẫn có thể sử dụng SSE2 khi bạn đã chuyển dữ liệu của bạn vào một ký ức liên kết đệm, nó khá dễ dàng - tôi đã sử dụng code here mà không cần bất kỳ vấn đề với intrinsics (nhưng đã có vấn đề với việc lắp ráp càng chi tiết here). Hy vọng điều này hữu ích - Tôi cũng đã làm việc với hình ảnh và lưu trữ chúng dưới dạng unsigned char trong bộ nhớ chính và sao chép chúng vào thanh ghi SSE2 (có ý nghĩa từ R, G, hoặc B thay đổi từ 0-255) - nhưng tôi đã sử dụng mã lắp ráp kể từ khi tôi cảm thấy nó dễ dàng hơn.

Nhưng nếu bạn muốn làm cho nền tảng chéo, tôi cho rằng việc sử dụng nội tại sẽ sạch hơn.

Chúc may mắn!

1

Tôi nghĩ rằng nút cổ chai hiệu suất của bạn có thể xuất phát từ quá trình truyền sang phao, đó là một hoạt động khá tốn kém.

Nếu tôi nhớ rõ, quá trình truyền đó khoảng 50 chu kỳ đồng hồ trong hầu hết các kiến ​​trúc ...và xem xét các trường hợp xấu nhất, trong đó phép nhân FP có thể kéo dài, chúng ta hãy nói, khoảng 4 đồng hồ mỗi một với không chồng chéo trong các đường ống, làm tất cả trong số họ song song trong 1 chu kỳ có thể giúp bạn tiết kiệm 15 chu kỳ tại hầu hết, vẫn không có được.

tôi muốn dứt khoát đi để làm việc luôn với định dạng cùng một số (số nguyên trong trường hợp này), nếu xem trực tiếp với MMX như Shmoopty nói, sau đó tốt hơn.

Các vấn đề liên quan