2013-03-06 23 views
5

tôi có mã trong đó kêu gọi rất nhiều_ftol2_sse, có các tùy chọn nhanh hơn không?

int myNumber = (int)(floatNumber); 

mà chiếm, trong tổng số, khoảng 10% thời gian CPU của tôi (theo hồ sơ). Trong khi tôi có thể để nó ở đó, tôi tự hỏi, nếu có những lựa chọn nhanh hơn, vì vậy tôi đã cố gắng tìm kiếm xung quanh, và stumbled khi

http://devmaster.net/forums/topic/7804-fast-int-float-conversion-routines/ http://stereopsis.com/FPU.html

tôi đã cố gắng thực hiện() chức năng Real2Int cho có nhưng nó cho tôi kết quả sai và chạy chậm hơn. Bây giờ tôi tự hỏi, có triển khai nhanh hơn để sàn đôi/phao giá trị để số nguyên, hoặc là phiên bản SSE2 nhanh như nó được? Các trang tôi tìm thấy ngày trở lại một chút, do đó, nó có thể chỉ là lỗi thời, và STL mới hơn là nhanh hơn lúc này.

Việc thực hiện không:

013B1030 call  _ftol2_sse (13B19A0h) 

013B19A0 cmp   dword ptr [___sse2_available (13B3378h)],0 
013B19A7 je   _ftol2 (13B19D6h) 
013B19A9 push  ebp 
013B19AA mov   ebp,esp 
013B19AC sub   esp,8 
013B19AF and   esp,0FFFFFFF8h 
013B19B2 fstp  qword ptr [esp] 
013B19B5 cvttsd2si eax,mmword ptr [esp] 
013B19BA leave 
013B19BB ret 

câu hỏi liên quan tôi thấy:

Fast float to int conversion and floating point precision on ARM (iPhone 3GS/4)

What is the fastest way to convert float to int on x86

Kể từ khi cả hai đều cũ, hoặc là ARM dựa, tôi tự hỏi nếu có cách hiện tại để làm điều này. Lưu ý rằng nó nói rằng chuyển đổi tốt nhất là một trong những điều không xảy ra, nhưng tôi cần phải có nó, do đó sẽ không thể.

Trả lời

6

Sẽ rất khó để đánh bại nếu bạn đang nhắm mục tiêu phần cứng chung x86. Thời gian chạy không biết chắc chắn rằng máy mục tiêu có một đơn vị SSE. Nếu nó đã làm, nó có thể làm những gì trình biên dịch x64 làm và inline một opcode cvttss2si. Nhưng kể từ khi thời gian chạy phải kiểm tra xem một đơn vị SSE có sẵn, bạn còn lại với việc thực hiện hiện tại. Đó là những gì thực hiện ftol2_sse. Và những gì nó vượt qua giá trị trong một đăng ký x87 và sau đó chuyển nó vào một thanh ghi SSE nếu một đơn vị SSE có sẵn.

Bạn có thể yêu cầu trình biên dịch x86 nhắm mục tiêu các máy có đơn vị SSE. Sau đó trình biên dịch thực sự sẽ phát ra một mã nội tuyến đơn giản là cvttss2si. Điều đó sẽ nhanh như bạn có thể nhận được. Nhưng nếu bạn chạy mã trên một máy cũ thì nó sẽ thất bại. Có lẽ bạn có thể cung cấp hai phiên bản, một cho các máy có SSE và một cho những máy không có.

Điều đó sẽ không giúp bạn đạt được nhiều như vậy. Nó chỉ sẽ tránh tất cả các chi phí của ftol2_sse điều đó xảy ra trước khi bạn thực sự đạt được mã vạch cvttss2si thực hiện công việc.

Để thay đổi cài đặt trình biên dịch từ IDE, hãy sử dụng Dự án> Thuộc tính> Thuộc tính cấu hình> C/C++> Tạo mã> Bật Bộ chỉ lệnh nâng cao. Trên dòng lệnh, nó là/arch: SSE hoặc/arch: SSE2.

+0

hoàn hảo, với mã x64 hoạt động nhanh hơn rất nhiều! – SinisterMJ

1

Đối double Tôi không nghĩ rằng bạn sẽ có thể cải thiện kết quả nhiều nhưng nếu bạn có rất nhiều float s để chuyển đổi rằng việc sử dụng một chuyển đổi đóng gói có thể giúp đỡ, sau đây là nasm mã:

global _start 

section .data 
    align 16 
    fv1: dd 1.1, 2.5, 2.51, 3.6 

section .text 
    _start: 

    cvtps2dq xmm1, [fv1] ; Convert four 32-bit(single precision) floats to 32-bit(double word) integers and place the result in xmm1 

Nên có mã nội tại cho phép bạn làm điều tương tự một cách dễ dàng hơn nhưng tôi không quen thuộc với việc sử dụng các thư viện nội tại. Mặc dù bạn không sử dụng gcc bài viết này Auto-vectorization with gcc 4.7 là một công cụ mở mắt về mức độ khó có thể làm cho trình biên dịch tạo ra mã vectơ tốt.

1

Nếu bạn cần tốc độ và một số lượng lớn máy mục tiêu, bạn nên giới thiệu một phiên bản SSE nhanh của tất cả các thuật toán của bạn, cũng như một thuật toán chung - và chọn các thuật toán được thực thi ở mức cao hơn nhiều.

Điều này cũng có nghĩa là ABI cũng được tối ưu hóa cho SSE; và bạn có thể vector hóa phép tính khi có sẵn và đó cũng là logic điều khiển được tối ưu hóa cho kiến ​​trúc.

btw. thậm chí chuỗi FLD; FIST sẽ mất không quá ~ 7 chu kỳ đồng hồ trên Pentium.

+3

Bạn cần thay đổi chế độ làm tròn để cắt chính xác. Thay đổi từ trạng thái x87 chậm, theo như tôi biết. –

+0

Nhận xét của @ infact là chính xác –

+0

Điểm tốt. Sau đó nó sẽ có ý nghĩa không thay đổi từ trạng thái _often_. –

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