2012-07-09 32 views
5

EDIT: Sau khi loại bỏ UB (vị trí tốt, tôi bỏ qua nó), thời gian là nhiều hơn hoặc ít giống hệt nhau. Sẽ gắn cờ một người kiểm duyệt để xóa nó.Tại sao di chuyển trở lại vào cuối chức năng kém hiệu quả?

Hai chức năng giống hệt nhau ngoại trừ một thực tế rằng foo có sự trở lại bên trong if, trên cả hai chi nhánh, trong khi goo có một đơn return ở cuối:

int foo() 
{ 
    static int x = 0; 
    if (x) 
    { 
     x > 2 ? x = 0 : ++x; 
     return x-1; 
    } 
    else 
    { 
     x++; 
     return x-1; 
    } 
} 
int goo() 
{ 
    static int x = 0; 
    if (x) 
    { 
     x > 2 ? x = 0 : ++x; 
    } 
    else 
    { 
     x++; 
    } 
    return x-1; 
} 

Những con số đang có chỉ để tối ưu hóa không khởi động quá mạnh và cuộc gọi hàm không được tối ưu hóa. Biên soạn với đầy đủ tối ưu hóa trên MSVS 2010.

Gọi chức năng 4000000000 lần, lấy mẫu 10 lần, fooluôn nhanh hơn:

  • foo - 8830 ms trung bình
  • goo - 8703 ms trung bình

Sự khác biệt là nhỏ, nhưng nó ở đó. Tại sao? Ngoài ra, tại sao trình biên dịch không tối ưu hóa chúng với cùng một thứ?

+1

Bạn đã kiểm tra đầu ra của bộ kết hợp chưa? –

+0

@larsmans yes, chức năng được gạch chân và phần đầu tiên là * lớn hơn * (mặc dù phải mất ít hơn). Tôi cũng đang xem xét các lý do ** tại sao ** trình biên dịch không thấy bất kỳ sự tối ưu hóa nào mà nó làm cho một trong số chúng. –

+0

Bạn đã xem mã ASM đã được sản xuất chưa? –

Trả lời

3

Hãy nhìn vào đầu ra của bộ kết hợp, có thể có một bước nhảy đến cuối hàm trong nhánh đầu tiên của goo().

+0

Có nhưng nhánh đầu tiên đó không bao giờ được lấy. – TerryE

+1

Tôi nghĩ rằng nó có liên quan đến dự đoán nhánh và đường ống. –

+1

@TerryE x là tĩnh, vì vậy nó được tăng lên trong bữa nửa buổi thứ hai và do đó nhánh đầu tiên được gọi trong một cuộc gọi hàm tiếp theo. –

0

Tôi giả định rằng đó là vì có lợi nhuận trong mỗi if, thời điểm hoạt động được thực hiện, foo sẽ trả về biến được tính toán.

goo, thậm chí nghĩ rằng nó làm điều tương tự, ngoại trừ hai trả về, vẫn sẽ phải kiểm tra các tuyên bố else.Đó sử dụng một số thời gian (cực kỳ nhỏ) nhưng như bạn có thể thấy, nó là mesurable.

+4

Bạn có ý gì khi kiểm tra câu lệnh 'else'? –

+0

Tôi không nghĩ rằng người khác cần phải được kiểm tra. Đầu tiên, không có "kiểm tra" một người khác. Khác là đúng nếu tất cả mọi thứ trước khi nó là sai. Ngoài ra, nếu điều kiện 'if' là đúng, khối' else' không bao giờ chạy, vì vậy tôi không thấy bất kỳ sự khác biệt nào trong công việc. Giống như những người khác nói, mã lắp ráp có thể khác nhau. – Brandon

-3

Trong trường hợp dấu ngoặc nhọn foo của "if" và "else" sẽ không được thực thi. Sau khi quay trở lại

tuyên bố điều khiển sẽ có được cú đúp kết thúc của hàm trực tiếp.

Thats lý do tại sao nó sẽ mất ít thời gian hơn cho foo.

+1

Naren, một lõi không thực hiện "niềng răng". Nó thực thi các lệnh. Tuy nhiên, bạn có quyền theo cách mà một số trình biên dịch căn chỉnh các mục tiêu nhánh trên 4/8 byte ranh giới để giúp cải thiện bộ nhớ đệm lệnh, và có thêm đích cũng như mã bổ sung cho 'return x + 1' đầu tiên có thể ảnh hưởng đến thời gian . – TerryE

+0

Tôi biết điều này là không thực hiện, nhưng tôi đã thử điều này bằng cách cho điểm break và thực hiện đã đi trực tiếp đến cú đúp cuối cùng của chức năng .... Bạn cũng thử với điểm ngắt và kiểm tra. – Narendra

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