2010-06-13 30 views
14

Vì vậy, bất cứ khi nào tôi viết mã, tôi luôn nghĩ về các tác động hiệu suất. Tôi thường tự hỏi, "chi phí" của việc sử dụng một memcopy liên quan đến các chức năng khác về mặt hiệu suất là gì? Ví dụ, tôi có thể đang viết một chuỗi các số tới một bộ đệm tĩnh và tập trung vào một khung trong bộ đệm, để giữ khung khi tôi đến cuối bộ đệm, tôi có thể ghi nhớ tất cả các số đó vào đầu hoặc tôi có thể thực hiện một thuật toán để phân bổ tính toán.Chi phí hoạt động của một bản ghi nhớ trong C/C++

+11

Bạn đã bao giờ vượt xa suy nghĩ về hiệu suất và đo nó chưa? –

+0

Tôi có, không phải cho memcopy mặc dù. – Cenoc

+6

Luôn luôn suy nghĩ về hiệu suất là một cách tuyệt vời để viết mã crappy (và có thể làm chậm). –

Trả lời

18

memcpy thường được tối ưu hóa để tối đa hóa băng thông bộ nhớ của các bản sao lớn. Tất nhiên, nó không phải là nhanh như tránh một bản sao hoàn toàn, và cho các bản sao ngắn kích thước cố định, chuyển nhượng trực tiếp có thể nhanh hơn kể từ memcpy có thêm mã để đối phó với độ dài lẻ.

Nhưng khi bạn cần sao chép một khối bộ nhớ, thật khó để đánh bại memcpy. Nó rất dễ xách tay và hầu hết các trình biên dịch đều có độ dài lớn để làm cho nó nhanh, cho dù đó là sử dụng hướng dẫn SIMD hay có thể là nội tuyến.

+1

Nên tránh sử dụng memcpy trong C++, vì đó là bản sao "câm" và những điều xấu có thể xảy ra. Các nhà điều hành gán/sao chép bản sao chắc chắn nên được sử dụng cách khác. Ngoài ra, một hồ sơ nên được chạy đầu tiên để xác định rằng đó là vấn đề. – Puppy

+13

@DeadMG: Rất nhiều chương trình C++ hoạt động trên dữ liệu "câm", được gọi là "dữ liệu cũ thuần túy" theo chuẩn C++ và hoàn toàn an toàn khi sử dụng memcpy. Theo kinh nghiệm của tôi, loại chương trình không có POD là các chương trình sẽ được viết tốt hơn bằng ngôn ngữ cấp cao hơn. –

+2

Có. Bạn * có thể * sử dụng memcpy và hoàn toàn vít chương trình của bạn lên với các loại không POD. Hoặc, bạn * có thể * sử dụng toán tử gán, mà cuối cùng sẽ dẫn đến một memcpy cho các loại POD và một chương trình hoạt động cho các loại không phải POD. – Puppy

1

Vâng, đầu tiên - bạn nên suy nghĩ về hiệu suất chỉ nếu bộ nhớ sao chép là bạn nút cổ chai(và nó thực sự là một trường hợp hiếm).

Thứ hai, memcpy được triển khai bằng cách sử dụng trình kết hợp (xem memcpy.asm) và, tôi đoán, là giải pháp sao chép bộ nhớ nhanh nhất hiện có.

Ngoài ra, nói chung, nói chung gọi memcpy thô trong C++ nên tránh, hãy thử sử dụng trình bao bọc trừu tượng hơn và các thường trình.

+0

Việc gán đơn giản có thể được thực hiện bằng cách sử dụng thanh ghi CPU, nhưng việc sử dụng memcpy không phải là trường hợp. Nếu quá trình gán quá lớn thì trình đăng ký trình biên dịch sẽ trở lại memcpy, vì vậy tốt hơn nên sử dụng gán (khi áp dụng ...) – MindTailor

1

memcpy() sao chép nội dung bộ nhớ trong nguồn tới đích. Sao chép rõ ràng là tuyến tính với số lượng các phần tử trong nguồn. Điều gì cấu thành kích thước tối ưu của một phần tử là máy phụ thuộc. Dù sao thì rất nhiều trình biên dịch otimization ma thuật đen có thể áp dụng tùy thuộc vào ngữ cảnh hoạt động. Trong C++ nó thường khôn ngoan hơn để tránh memcpy và sử dụng các phép gán hoặc sao chép.

+0

Trên kiến ​​trúc hiện đại, lấy kiến ​​trúc bộ nhớ và hiệu ứng bộ nhớ cache, sao chép gần như chắc chắn không phải là tuyến tính số lượng phần tử. memcpy và copy constructor đang so sánh táo và cam. –

4

Bạn có thể xem xét các hàm ý hiệu suất, nhưng đừng trở nên quá mất tập trung so với mục tiêu thực sự của việc viết mã sạch tốt. Nếu bạn có khuynh hướng ám ảnh về hiệu suất ngay cả khi bạn biết rõ hơn, hãy cố gắng tập trung vào các hàm ý mức cao hơn và bỏ qua các công cụ từng bit như memcpy, bạn có thể tin tưởng trình biên dịch và tác giả thư viện để tối ưu hóa.

Thường tránh tối ưu hóa sớm loại này ở mức thấp vì nó tiêu tốn thời gian của bạn, hiệu ứng bong bóng lên để lây nhiễm toàn bộ chương trình, và không có phép đo, bạn không thể mong đợi đạt được hiệu suất.

1

Hãy xem xét cuốn sách 'Hoàn thành mã' của McCormick. Trộm cắp không biết xấu hổ từ đó ---

  1. Cải tiến thuật toán thường có hiệu suất hoàn vốn lớn nhất.

  2. Các câu lệnh đơn giản cho phép trình biên dịch tối ưu hóa hiệu quả. Chúng có chi phí lập trình thấp. Chúng thường tăng khả năng đọc. Họ là một mặc định chi phí thấp 'nên' anyway.

Đã đề cập memcpy đã được tinh chỉnh và thường thực sự hiệu quả trên các khối bộ nhớ lớn hơn.Vì vậy, tại sao tránh nó nếu tình hình ra lệnh giữ dữ liệu?

Nói chung không tối ưu hóa vì không có lý do gì. Giả sử bạn viết một báo cáo chống lại một tập dữ liệu khổng lồ. Không người dùng nào mong đợi có phản hồi ngay lập tức trong trường hợp đó. Họ bắt đầu công việc và đi ăn nhẹ. Vì vậy, nếu mã của bạn chạy trong 10 phút hoặc ba phút không quan trọng. Đối với họ. Thet sẽ không nhận ra. Và ... họ viết tiền lương của bạn.

Tối ưu hóa lập trình là chi phí trả trước rất lớn. Vì vậy, chi tiêu mà chi phí chỉ khi cần thiết.

+1

Thực ra, đó là mã của Steve Mcconnell Hoàn thành –

+0

CNTT là McConnell. Tôi đứng sửa. –

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