2013-05-29 66 views
12

Có _mm_div_ps cho phân chia giá trị dấu phẩy động, có _mm_mullo_epi16 cho phép nhân số nguyên. Nhưng có cái gì đó cho phân chia số nguyên (16 bit giá trị)? Làm thế nào tôi có thể tiến hành phân chia như vậy?Phân chia số nguyên SSE?

+0

Không đủ người cần nó, vì vậy ... –

+0

Nope nó không tồn tại. Nó có lẽ là sự kết hợp của không đủ người cần nó cùng với những khó khăn (và chết-không gian) của một đơn vị phân chia số nguyên. – Mysticial

+0

Bạn có muốn chia cho một hằng số hoặc bằng một biến không? –

Trả lời

8

Xin xem vectorclass Agner Sương mù của ông đã thực hiện một thuật toán nhanh để làm phân chia số nguyên với SSE/AVX cho 8-bit, 16-bit, và lời nói-bit 32 (nhưng không phải 64-bit) http://www.agner.org/optimize/#vectorclass

Look trong tập tin vectori128.h để biết mã và mô tả của algoirthm như hướng dẫn sử dụng tốt của ông, VectorClass.pdf

Đây là một đoạn mô tả thuật toán từ sách hướng dẫn của ông.

"bộ phận Integer Không có hướng dẫn trong lệnh x86 thiết lập và mở rộng của nó có hữu ích cho bộ phận vector nguyên và hướng dẫn như vậy sẽ khá chậm nếu họ tồn tại. Vì vậy, các thư viện lớp vector là sử dụng một Nguyên tắc cơ bản của thuật toán này có thể được thể hiện trong công thức này: a/b ≈ a * (2n/b) >> n Tính toán này đi qua các bước sau: 1. tìm một giá trị cho n 2. tính 2n/b 3. tính toán sửa đổi cần thiết cho làm tròn lỗi 4. làm phép nhân bật và dịch chuyển sang phải và áp dụng các sửa chữa để làm tròn số lỗi

Công thức này có lợi nếu nhiều số được chia cho cùng một số chia b. Các bước 1, 2 và 3 chỉ cần thực hiện một lần trong khi bước 4 được lặp lại cho mỗi giá trị của cổ tức a. Các chi tiết toán học được mô tả trong tệp vectori128.h. (Xem thêm T. Granlund và PL Montgomery: Chia theo Số bất biến Số nguyên Sử dụng Phép nhân, Kỷ yếu của SIGPLAN. "...

Chỉnh sửa: gần cuối tập tin vectori128.h cho biết cách thực hiện phân chia ngắn với một biến vô hướng "Mất nhiều thời gian hơn để tính toán các tham số được sử dụng để phân chia nhanh hơn là làm phân chia. Do đó, việc sử dụng cùng một đối tượng chia số sẽ mất nhiều thời gian hơn. 10:

short x = 10; 
uint16_t dividends[80], quotients[80];   // numbers to work with 
Divisor_us div10(x);       // make divisor object for dividing by 10 
Vec8us temp;         // temporary vector 
for (int i = 0; i < 80; i += 8) {    // loop for 4 elements per iteration 
    temp.load(dividends+i);     // load 4 elements 
    temp /= div10;        // divide each element by 10 
    temp.store(quotients+i);     // store 4 elements 
} 

"

Edit: phân chia số nguyên bởi một vector của quần short

#include <stdio.h> 
#include "vectorclass.h" 

int main() {  
    short numa[] = {10, 20, 30, 40, 50, 60, 70, 80}; 
    short dena[] = {10, 20, 30, 40, 50, 60, 70, 80}; 

    Vec8s num = Vec8s().load(numa); 
    Vec8s den = Vec8s().load(dena); 

    Vec4f num_low = to_float(extend_low(num)); 
    Vec4f num_high = to_float(extend_high(num)); 
    Vec4f den_low = to_float(extend_low(den)); 
    Vec4f den_high = to_float(extend_high(den)); 

    Vec4f qf_low = num_low/den_low; 
    Vec4f qf_high = num_high/den_high; 
    Vec4i q_low = truncate_to_int(qf_low); 
    Vec4i q_high = truncate_to_int(qf_high); 

    Vec8s q = compress(q_low, q_high); 
    for(int i=0; i<8; i++) { 
     printf("%d ", q[i]); 
    } printf("\n"); 
} 
+1

Điều này chỉ thực sự hữu ích cho việc phân chia theo hằng số - OP đã nói rằng anh ta muốn chia cho một biến, trong trường hợp này tôi nghĩ tùy chọn duy nhất là giải nén, chuyển đổi thành phao và thực hiện phép chia trong phao. –

+0

@PaulR, tôi đã thêm bản chỉnh sửa để phản hồi nhận xét của bạn. Đến cuối tập tin vectori128.h ông đưa ra một ví dụ về cách làm các bộ phận của quần short với các biến. Tôi đã không đi qua các chi tiết bởi vì phân chia số nguyên đã không được một cổ chai trong mã của tôi chưa (những lần tôi đã phải sử dụng nó tôi đã làm nó bằng cách chuyển bit ngay mà là rất nhanh). –

+0

@PaulR, vì vậy tôi đã xem xét kỹ hơn. Phương pháp nhanh trong VectorClass chỉ hoạt động đối với vô hướng. Đối với phân chia số nguyên véc tơ/vector thì tôi nghĩ bạn đã đúng. Giải pháp duy nhất, nếu bạn phải làm interger vector/vector, là hoặc là chuyển đổi sang phao nổi, làm các bộ phận, và chuyển đổi trở lại quần short. Tôi đã thêm một bản chỉnh sửa làm điều đó. Tôi đoán bạn cũng có thể lưu quần short vào một mảng làm phân chia vô hướng và sau đó tải chúng trở lại là tốt. –

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