2010-03-03 26 views
6

Mà, trung bình, nhanh hơn - kiểm tra giá trị sau đó, nếu cần, chỉ định hoặc chỉ đơn giản là gán? Hoặc, trong C++ ngữ:Đọc rồi viết có điều kiện so với viết

bool b; 
if(b) 
    b = false; 

hoặc

b = false; 

Giả thiết rằng nếu() điều kiện là đúng với 50% xác suất. Câu trả lời sẽ có nhiều khả năng phụ thuộc vào kiến ​​trúc cao nhất - hãy nói lên những cân nhắc cấp thấp của bạn. Viết luôn luôn dirties dòng bộ nhớ cache - phải không? Vì vậy, bằng cách tránh viết, chúng tôi tránh một bộ nhớ cache tuôn ra trong 0,5 trường hợp. Nhưng một bộ nhớ cache đủ thông minh có thể phát hiện một ghi nhỏ và không bẩn chính nó. Nhưng viết vô điều kiện luôn luôn chính xác là một hoạt động bộ nhớ, và đọc-ghi là, trung bình, 1.5 hoạt động.

Tuyên bố từ chối trách nhiệm: đây là câu hỏi tò mò, không phải vấn đề tôi thực sự phải đối mặt.

+0

liệu nó có quan trọng một cách hợp lý những gì b là nếu chúng kết thúc kết quả là b phải sai? –

+0

@ mờ: đây là về tối ưu hóa, không phải về logic. –

+0

có, nhưng điều thứ hai dễ đọc hơn và cho biết ý kiến ​​của tôi là gì. – Earlz

Trả lời

4

Chi nhánh đắt tiền trên CPU hiện đại và truy cập bộ nhớ là tốn kém trên các CPU nhúng/cũ hơn. Vì vậy, căn hộ chỉ-assign sẽ luôn luôn được nhanh hơn, trừ khi bạn có một số bộ nhớ kinda lạ mà mất nhiều thời gian để viết hơn đọc (gợi ý: bạn không)

Đó là tồi tệ hơn vì những lý do cụ thể:

  • Hướng dẫn phân nhánh. Điều này có thể được dự đoán bởi bộ xử lý, nhưng nó vẫn phải chịu một khả năng trên cao.
  • 2 truy cập bộ nhớ thay vì 1. Đọc và Viết trên hầu hết các hình thức bộ nhớ đều có cùng tốc độ, vậy tại sao lại thực hiện hai lần khi bạn có thể làm điều đó một lần?
  • Chi phí mã khác. đây là một vi mô, nhưng các hướng dẫn khác phải được phát ra để thực hiện câu lệnh if.Vì vậy, có nghĩa là một bộ nhớ thêm vài lần đọc và không gian nhiều hơn không cần thiết tiêu thụ trong bộ nhớ cache.
  • Và vì bi quan, điều đó có nghĩa là trình biên dịch C++ quyết định đặt biến này vào sổ đăng ký thay vì các biến cần thiết khác ..
  • Ngoài ra, nếu bạn giả định b. Đăng ký đọc/ghi là rất rẻ, nhưng họ không được tự do ..
+0

Điểm tốt về dự đoán nhánh (sai); hiện nó vẫn áp dụng trên CPU ARM nơi if() như thế này được thực hiện mà không có bất kỳ phân nhánh? –

+0

Nó sẽ vẫn chậm hơn vì đọc thêm bộ nhớ .. Ngay cả khi bạn có một số lệnh ma thuật 'read-and-set-false-if-true', bộ xử lý vẫn phải đọc giá trị từ bộ nhớ để kiểm tra xem nó là sự thật .. Và đối với việc phân nhánh trên ARM, không, các nhánh không thực sự áp dụng cho việc gán điều kiện. trong x86 'ccmov' không có chi nhánh mà tôi không tin .. – Earlz

+0

Vì vậy, sự sụp đổ lớn của R-W - misprediction chi nhánh - không áp dụng trên ARM. Các downer lớn của W - bộ nhớ cache tuôn ra - vẫn không, phải không? –

1

Nó chắc chắn sẽ có giá trị để lược tả điều này trên các kiến ​​trúc khác nhau để có được kết quả thực tế.

1

Nó phụ thuộc vào nhiều thứ:

  • thế nào có thể dự đoán các chi nhánh là (trong kịch bản đầu tiên)
  • liệu b là đã có trong một thanh ghi
  • gì kiến ​​trúc bạn đang sử dụng
1

Ngoài các gợi ý cho hồ sơ, nó cũng thực sự phụ thuộc vào bộ nhớ sao lưu yêu cầu ghi đó - nếu đó là thiết bị flash được ánh xạ bộ nhớ, ví dụ, việc ghi có thể cực kỳ tốn kém.

0

Nếu bạn đang thực hiện chuyển nhượng con trỏ, tham chiếu hoặc loại giá trị cơ bản, cá nhân tôi cho rằng việc chuyển nhượng trực tiếp sẽ nhanh hơn (muốn xem kết quả trên hồ sơ). Trong môi trường xác suất 50%, bạn sẽ tiềm năng thực hiện nhiều hướng dẫn hơn đưa giá trị vào thanh ghi. Việc gán đối tượng struct hoặc class để kích hoạt toán tử gán sẽ là đắt nhất. Logic điều kiện cũng giới thiệu thêm hướng dẫn và nó thêm vào các chỉ số phức tạp mã

1

Gần đây tôi đã đọc các bài báo về kỹ thuật nén rất nhanh và kẻ nhấn mạnh rằng cần phải tránh phân nhánh if để đạt hiệu suất tốt nhất. Lý do là CPU pipelining. Sử dụng if s phá vỡ nhiều tối ưu hóa một CPU có thể thực hiện để thực thi các phần của mã song song. Vì vậy, nếu bạn có nhiều thao tác này, có thể sử dụng nhanh hơn b = false.

1

Trên một bộ vi xử lý hiện đại pipelined bạn cần phải thực hiện việc này vào tài khoản:

  • một chi nhánh mispredicted tốn rất nhiều
  • cửa hàng và tải mất một thời gian dài
  • cache có thể tăng tốc cả đọc và viết, của bộ nhớ cache.

Đọc với ghi có điều kiện có ít nhất quyền truy cập bộ nhớ và chi nhánh có thể đoán sai. Giả sử chi nhánh được lấy 50% thời gian, bạn có 1,5 truy cập bộ nhớ trung bình, cộng với cơ hội giả mạo.

Ghi vô điều kiện có chính xác quyền truy cập bộ nhớ và không có chi nhánh nào.

Bây giờ bạn cần phải cân bằng chi phí giả mạo với chi phí của một cửa hàng, thay đổi tùy thuộc vào số lượng tác nhân bộ nhớ cache bạn có.

+0

Tính toán tốt! – pajton

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