2012-01-31 36 views
17

Một hoạt động chung mà tôi thực hiện trong chương trình của tôi là chia tỷ lệ vectơ theo vô hướng (V * s, ví dụ [1,2,3,4] * 2 == [2,4, 6,8]). Có hướng dẫn SSE (hoặc AVX) để thực hiện việc này hay không, trước khi nạp vô hướng ở mọi vị trí trong vec-tơ (ví dụ: _mm_set_ps (2,2,2,2)) và sau đó nhân?SSE (SIMD): nhân vectơ theo vô hướng

Đây là những gì tôi làm bây giờ:

__m128 _scalar = _mm_set_ps(s,s,s,s); 
__m128 _result = _mm_mul_ps(_vector, _scalar); 

Tôi đang tìm một cái gì đó giống như ...

__m128 _result = _mm_scale_ps(_vector, s); 

Trả lời

13

Tùy thuộc vào trình biên dịch của bạn, bạn có thể cải thiện hệ mã một chút bằng cách sử dụng _mm_set1_ps:

const __m128 scalar = _mm_set1_ps(s); 
__m128 result = _mm_mul_ps(vector, scalar); 

hằng Tuy nhiên vô hướng như thế này chỉ nên cần phải được khởi tạo một lần, bên ngoài bất kỳ vòng lặp, do đó hiệu suất chi phí nên không liên quan. (Trừ khi giá trị vô hướng đang thay đổi trong vòng lặp?)

Như mọi khi, bạn nên xem mã trình biên dịch tạo và cũng thử chạy mã của bạn dưới một trình lược tả phong nha để xem các điểm nóng thực sự ở đâu.

0

Tôi không biết về bất kỳ chỉ dẫn duy nhất mà những gì bạn muốn. Các hoạt động thiết lập thực sự là một nút cổ chai? Nếu bạn nhân một vectơ lớn với cùng một hằng số, thì thời gian cần để điền vào một thanh ghi XMM/YMM với bốn bản sao của hằng số phải là một phần rất nhỏ trong tổng thời gian thực hiện.

Là một tối ưu hóa đơn giản, nếu hằng số là 2 như trong ví dụ của bạn, bạn có thể thay thế nhân với lệnh thêm thay thế, không yêu cầu bất kỳ hằng số nào.

4

Không có hướng dẫn nhân phép nhân vectơ bằng vô hướng. Tuy nhiên, có một số hướng dẫn để tải các giá trị vô hướng giống nhau vào tất cả các vị trí trong thanh ghi vector.

Bộ chỉ dẫn AVX cung cấp _mm_broadcast_ss/_mm256_broadcast_ss/_mm256_broadcast_sd nội tại để điền vào sổ đăng ký SSE và AVX với cùng giá trị float/double.

Trong bộ chỉ lệnh SSE3, bạn có thể tìm thấy _mm_loaddup_pd nội tại có thể đăng ký thanh ghi SSE với cùng một giá trị kép.

Trong các phiên bản khác của SSE thường là lựa chọn tốt nhất là để tải một giá trị vô hướng sử dụng _mm_load_ss/_mm_load_sd và sau đó sao chép nó vào tất cả các yếu tố của một thanh ghi vector với _mm_shuffle_ps/_mm_unpacklo_pd.