2015-02-04 21 views
7

Trong C++, tôi đang cố gắng viết một trình bao bọc xung quanh một số nguyên 64 bit. Kỳ vọng của tôi là nếu được viết chính xác và tất cả các phương thức được gạch chân như vậy thì trình bao bọc phải là biểu diễn như kiểu thực. Câu trả lời cho điều này question trên SO dường như đồng ý với kỳ vọng của tôi.Tại sao VC++ không thể tối ưu hóa một trình bao bọc số nguyên?

tôi đã viết mã này để kiểm tra sự mong đợi của tôi:

class B 
{ 
private: 
    uint64_t _v; 

public: 
    inline B() {}; 
    inline B(uint64_t v) : _v(v) {}; 

    inline B& operator=(B rhs) { _v = rhs._v; return *this; }; 
    inline B& operator+=(B rhs) { _v += rhs._v; return *this; }; 
    inline operator uint64_t() const { return _v; }; 
}; 

int main(int argc, char* argv[]) 
{ 
    typedef uint64_t; 
    //typedef B T; 
    const unsigned int x = 100000000; 

    Utils::CTimer timer; 
    timer.start(); 

    T sum = 0; 
    for (unsigned int i = 0; i < 100; ++i) 
    { 
     for (uint64_t f = 0; f < x; ++f) 
     { 
     sum += f; 
     } 
    } 

    float time = timer.GetSeconds(); 

    cout << sum << endl 
     << time << " seconds" << endl; 

    return 0; 
} 

Khi tôi chạy này với typedef B T; thay vì typedef uint64_t T thời gian báo cáo luôn chậm hơn 10% khi được biên dịch với VC++. Với g ++ các màn trình diễn giống nhau nếu tôi sử dụng trình bao bọc hay không.

Vì g ++ hiện nó tôi đoán không có lý do kỹ thuật tại sao VC++ không thể tối ưu hóa chính xác điều này. Có điều gì tôi có thể làm để làm cho nó tối ưu hóa nó?

Tôi đã cố gắng để chơi với optimisations cờ không thành công

+0

Bạn có chạy mã từ Visual Studio hoặc từ một bảng điều khiển Windows không? – jpo38

+0

Tôi sẽ không ngạc nhiên nếu g ++ gấp toàn bộ vòng lặp. –

+1

Lặn vào lắp ráp được tạo ra! –

Trả lời

3

Sử dụng /O2 (tối đa hóa tốc độ), cả hai lựa chọn thay thế tạo giống hệt nhau lắp ráp sử dụng Visual Studio 2012. Đây là mã của bạn, trừ đi thời gian và đầu ra:

00FB1000 push  ebp 
00FB1001 mov   ebp,esp 
00FB1003 and   esp,0FFFFFFF8h 
00FB1006 sub   esp,8 
00FB1009 mov   edx,64h 
00FB100E mov   edi,edi 
00FB1010 xorps  xmm0,xmm0 
00FB1013 movlpd  qword ptr [esp],xmm0 
00FB1018 mov   ecx,dword ptr [esp+4] 
00FB101C mov   eax,dword ptr [esp] 
00FB101F nop 
00FB1020 add   eax,1 
00FB1023 adc   ecx,0 
00FB1026 jne   main+2Fh (0FB102Fh) 
00FB1028 cmp   eax,5F5E100h 
00FB102D jb   main+20h (0FB1020h) 
00FB102F dec   edx 
00FB1030 jne   main+10h (0FB1010h) 
00FB1032 xor   eax,eax 

Tôi cho rằng thời gian đo dao động hoặc không phải lúc nào cũng chính xác.

+0

'xmm0'! Đăng ký MMX! Nó * đã * vector hóa hoạt động! –

+0

@PanagiotisKanavos Thật vậy, một cảnh tượng hiếm hoi tôi muốn nói. – Daerst

+1

Không thực sự hiếm hoi, VC chỉ bị vượt qua bởi các trình biên dịch riêng của Intel trong việc song song mã. –

4

Đối với hồ sơ, đây là những gì g ++ và kêu vang ++ 's lắp ráp tạo ra tại -O2 dịch để (trong cả hai trường hợp wrapper và phi wrapper), modulo phần thời gian:

sum = 499999995000000000; 
cout << sum << endl; 

Nói cách khác, nó tối ưu hóa lặp lại hoàn toàn. Bất kể bạn cố gắng vectơ vòng lặp như thế nào, thật khó để đánh bại không lặp lại chút nào :)

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