2012-05-15 35 views
6

Làm cách nào tôi có thể lấy nghịch đảo (nghịch đảo) của phao bằng lệnh SSE, nhưng chỉ cho các giá trị khác không phải là?SSE: nghịch đảo nếu không không

Bối cảnh dưới đây:

Tôi muốn bình thường hóa một loạt các vectơ để mỗi chiều có tỷ lệ trung bình tương tự. Trong C, mã này có thể được mã hóa là:

float vectors[num * dim]; // input data 

// step 1. compute the sum on each dimension 
float norm[dim]; 
memset(norm, 0, dim * sizeof(float)); 
for(int i = 0; i < num; i++) for(int j = 0; j < dims; j++) 
    norm[j] += vectors[i * dims + j]; 
// step 2. convert sums to reciprocal of average 
for(int j = 0; j < dims; j++) if(norm[j]) norm[j] = float(num)/norm[j]; 
// step 3. normalize the data 
for(int i = 0; i < num; i++) for(int j = 0; j < dims; j++) 
    vectors[i * dims + j] *= norm[j]; 

Bây giờ vì lý do hiệu suất, tôi muốn thực hiện việc này bằng nội dung SSE. Setp 1 và bước 3 là dễ dàng, nhưng tôi đang mắc kẹt ở bước 2. Tôi dường như không tìm thấy bất kỳ mẫu mã hoặc hướng dẫn SSE rõ ràng để lấy các recirpocal của một giá trị nếu nó không phải là số không. Đối với sự phân chia, _mm_rcp_ps thực hiện thủ thuật, và có thể kết hợp nó với một động thái có điều kiện, nhưng làm thế nào để có được một mặt nạ cho biết thành phần nào là 0?

Tôi không cần mã cho các thuật toán mô tả ở trên, chỉ là "nghịch đảo nếu không zero" chức năng:

__m128 rcp_nz_ps(__m128 input) { 
    // ???? 
} 

Cảm ơn!

Trả lời

11
__m128 rcp_nz_ps(__m128 input) { 
    __m128 mask = _mm_cmpeq_ps(_mm_set1_ps(0.0), input); 
    __m128 recip = _mm_rcp_ps(input); 
    return _mm_andnot_ps(mask, recip); 
} 

Mỗi làn đường của mask được thiết lập để một trong hai b111...11 nếu đầu vào là zero, và b000...00 khác. Và không phải với mặt nạ đó thay thế các phần tử của nghịch đảo tương ứng với một đầu vào bằng 0 bằng không.

+1

Chết tiệt, nhanh quá. Tôi đã làm việc một mình và bạn đánh tôi với nó. +1 – Mysticial

+0

Cảm ơn. Có cách nào để "kiểm tra" thay vì "so sánh", và tránh sử dụng một thiết lập đăng ký để null? Chỉ cần tự hỏi ... – Antoine

+0

Bên cạnh dòng cuối cùng, có lỗi chính tả: đầu vào phải được trả về. – Antoine

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