2010-10-04 40 views
6

Sao chép mã is usually bad và thường khá dễ phát hiện. Tôi cho rằng các trình biên dịch có thể phát hiện tự động trong các trường hợp dễ dàng nhất - chúng đã phân tích cú pháp văn bản và nhận được biểu diễn trung gian mà chúng phân tích theo nhiều cách khác nhau - phát hiện các mẫu đáng ngờ như biến chưa được khởi tạo, tối ưu hóa mã đã phát, v.v. mã theo cách này và xử lý nó trong khi phát ra mã máy.Trình biên dịch C++ có thể tự động loại bỏ mã trùng lặp không?

Có trình biên dịch C++ nào có thể phát hiện mã trùng lặp và chỉ phát ra mã máy tương ứng một lần thay vì cho mỗi bản sao trong văn bản nguồn không?

+1

Trình biên dịch của người lười biếng? – Stephen

+1

Tôi không nghĩ rằng đó là ưu tiên cao đối với người triển khai trình tối ưu hóa, vì loại mã trùng lặp này sẽ bị bắt ở cấp đánh giá của người quản lý nhóm/mã. Hay đúng hơn, mức độ "thực hành tốt" ... – DevSolar

+0

@Stephen: Có.Chúng tôi đã đạt đến điểm khi trình biên dịch phát ra mã đủ hiệu quả để không quan tâm đến việc tối ưu hóa vi mô. – sharptooth

Trả lời

9

Một số có, một số thì không.

Từ trang tối ưu hóa của LLVM: -mergefunc (MergeFunctions pass, how it works)

Các chức năng được tách ra trong các khối nhỏ ở Trung Đại diện LLVM, tối ưu hóa này vượt qua cố gắng kết hợp các khối tương tự. Nó không đảm bảo thành công mặc dù.

Bạn sẽ tìm thấy nhiều tối ưu hóa khác trên trang này, mặc dù một số trong số chúng có thể xuất hiện khó hiểu ngay từ cái nhìn đầu tiên.

Tôi sẽ thêm ghi chú mặc dù mã trùng lặp không quá tệ đối với trình biên dịch/thực thi, không tốt cho điểm bảo trì và không có trình biên dịch nào có thể thực hiện được.

+0

tôi sẽ nghĩ rằng ngay cả khi nó thành công nó không được đảm bảo để cải thiện tốc độ. tất nhiên một số người cần tối ưu hóa dung lượng trống +1 –

+0

Thú vị. Tôi không biết những gì họ có nghĩa là "overridable", nhưng bạn thường không thể làm điều này với các chức năng C, vì bình đẳng được xác định trên con trỏ chức năng. – Potatoswatter

+0

@jk: Tôi đồng ý rằng tốc độ có thể không được cải thiện, tôi nghĩ rằng điều này đi ngược lại với việc tối ưu hóa bỏ vòng lặp truyền thống. Tuy nhiên bạn có thể với khung LLVM xác định thứ tự bạn muốn áp dụng tối ưu hóa, vì vậy bạn có thể có các twos. Họ không chính xác nếu một loại heuristic được áp dụng (tùy thuộc vào kích thước của mã?). Một mặt, nó phát sinh một bước nhảy đến một vị trí bộ nhớ khác, mặt khác mã càng ít thì nó càng nằm trong bộ nhớ cache ... vì vậy tôi đoán rằng, một lần nữa, bạn chỉ cần đo lường phần nhỏ của riêng bạn mã :) –

8

Tôi nghĩ rằng câu hỏi đưa ra giả định sai rằng các trình biên dịch sẽ luôn luôn muốn loại bỏ trùng lặp mã. mã trùng lặp là xấu cho khả năng đọc/bảo trì mã nguồn không nặc thời hiệu suất của mã được biên dịch, thực sự người ta có thể xem xét loop unrolling làm trình biên dịch thêm mã trùng lặp để tăng tốc độ. biên dịch mã không cần phải làm theo các nguyên tắc tương tự như mã nguồn và thường không như nó là dành cho máy không cho con người để đọc.

trình biên dịch thông thường đang bận biên dịch không chuyển đổi mã nguồn, tất nhiên các IDE có thể cho phép cả hai.

+2

Mã hợp nhất làm giảm kích thước của thư viện được tạo ra/tệp thực thi, do đó nó có thể tăng tốc quá trình thực hiện. Tôi đồng ý nó sẽ xung đột phần nào với vòng lặp unrolling mặc dù. –

+3

như với hầu hết mọi thứ có một thương mại tắt, nhưng imho giả định rằng trình biên dịch nên luôn luôn cố gắng để loại bỏ trùng lặp là sai –

+2

Tôi không thấy nơi mà câu hỏi này làm cho một giả định ở tất cả. Nó hỏi xem có bất kỳ trình biên dịch nào làm điều đó, không phải cho dù đó là một ý tưởng hay, hay các trình biên dịch * có thể * làm điều đó luôn luôn * sẽ * làm điều đó. –

1

Visual C++ thực hiện việc này nếu bạn chỉ định 'thu nhỏ kích thước mã' (/ O1). Chức năng được cung cấp được mô tả trong tài liệu cho /Og, không được dùng nữa vì lợi ích của các tùy chọn bắt trọn đơn giản hơn để ủng hộ kích thước hoặc tốc độ ưu tiên (/ O2).

3

Từ kiến ​​thức của tôi, việc loại bỏ mã thường không xảy ra trên các chức năng. Vì vậy, nếu bạn viết một số đoạn mã trùng lặp trong hai hàm khác nhau thì sẽ có rất ít cơ hội (gần như không có) đoạn mã đó sẽ bị loại bỏ.

Có một số tối ưu hóa như return value optimization, function inlining có thể xảy ra trên các chức năng. Tuy nhiên hầu hết các tối ưu hóa được thực hiện trong chính function.This thường không được thực hiện ở cấp độ ngôn ngữ cao hơn, bởi điều này tôi có nghĩa là trình biên dịch sẽ không nhìn vào mã C + + và bắt đầu tối ưu hóa nó. Trình biên dịch chủ yếu có một đại diện trung gian, giữa ngôn ngữ cấp cao (C++) và ngôn ngữ máy. Đại diện trung gian này (IR) có phần tương tự với ngôn ngữ máy nhưng không chính xác là ngôn ngữ máy của hệ thống mà trên đó mã được biên dịch. Tham khảo trang wiki http://en.wikipedia.org/wiki/Compiler_optimization, nó liệt kê một số tối ưu hóa đó

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