2008-11-24 42 views
28

Tôi đang đọc qua K & R và đến phần nhỏ trên các biến đăng ký, và đã tự hỏi liệu mọi người ở đây có một số ví dụ hay về điều này được đưa vào thực tế hay không.Ví dụ điển hình về việc sử dụng biến đăng ký trong C là gì?

Từ mục 4.7 trong K & R:

Tờ khai đăng ký trông giống như
đăng ký int x;
đăng ký char c;

Để rõ ràng, tôi chỉ hy vọng sẽ thấy một số mẫu mã thú vị. Tôi (khá chắc chắn rằng tôi) hiểu chủ đề vì vậy không cảm thấy cần phải gõ lên một lời giải thích chi tiết (trừ khi bạn muốn).

Trả lời

64

Không có ví dụ điển hình về việc sử dụng đăng ký khi sử dụng trình biên dịch hiện đại (đọc: 15+ năm qua) vì gần như không bao giờ làm tốt và có thể làm xấu. Khi bạn sử dụng đăng ký, bạn đang nói với trình biên dịch "Tôi biết làm thế nào để tối ưu hóa mã của tôi tốt hơn bạn làm" mà là gần như không bao giờ là trường hợp. Một trong ba điều có thể xảy ra khi bạn sử dụng đăng ký:

  • Trình biên dịch bỏ qua nó, điều này rất có thể xảy ra. Trong trường hợp này, tác hại duy nhất là bạn không thể lấy địa chỉ của biến trong mã.
  • Trình biên dịch tôn trọng yêu cầu của bạn và kết quả là mã chạy chậm hơn.
  • Trình biên dịch tôn trọng yêu cầu của bạn và mã chạy nhanh hơn, đây là kịch bản ít có khả năng nhất.

Thậm chí nếu một trình biên dịch tạo mã tốt hơn khi bạn sử dụng đăng ký, không có lý do gì để tin rằng người khác sẽ làm như vậy. Nếu bạn có một số mã quan trọng mà trình biên dịch không tối ưu hóa tốt, thì đặt cược của bạn tốt nhất có lẽ là sử dụng trình assembler cho phần đó, nhưng tất nhiên làm việc lược tả thích hợp để xác minh mã được tạo ra thực sự là vấn đề đầu tiên.

+3

"Ba điều có thể xảy ra và hai điều xấu"? Nơi mà tôi đã nghe nói rằng trước khi ... ;-) –

+0

Hãy nhớ rằng trình biên dịch là hoàn toàn miễn phí để bỏ qua đề xuất của bạn - không có gì trong tiêu chuẩn để nói rằng nó đã đặt một biến đăng ký trong một đăng ký. –

+0

cũng có thể là trường hợp bạn viết trình biên dịch phụ trợ và bạn nói "đăng ký" cho tất cả người dân địa phương trong một hàm sẽ tạo ra một chức năng ngăn xếp. đó sẽ là khá hữu ích tôi nghĩ. –

10

Nói chung, tôi đồng ý với Robert, nhưng cũng như bất kỳ quy tắc nào khác, quy tắc này cũng có ngoại lệ.
Nếu bạn làm việc trên hệ thống nhúng sâu, bạn có thể biết rõ hơn trình biên dịch cách tối ưu hóa mã cho ứng dụng cụ thể của bạn trên kiến ​​trúc phần cứng cụ thể của bạn.

Nhưng trong 99% trường hợp, Roberts cũng giải thích tốt cho từ được nhúng.

+2

Điều này trông khá giống với những gì Robert nói, trong sự trung thực. –

+0

Thực ra bạn đúng loại. Tôi đọc lại bài viết và đoạn cuối cùng là làm rõ những gì tôi muốn làm rõ ... Lần sau tôi sẽ đọc tốt hơn – Ilya

3

Một trường hợp phổ biến khác là khi triển khai thông dịch viên cấp thấp. Giữ một số trạng thái trong sổ đăng ký, ví dụ: con trỏ ngăn xếp máy ảo, có thể giảm đáng kể khả năng truy cập bộ nhớ và tăng tốc độ mã của bạn.

Xem vmgen — a generator of efficient virtual machine interpreters để biết ví dụ về tối ưu hóa (5.2 Bộ đệm ẩn hàng đầu).

1

trước tiên, biến đăng ký phải được sử dụng cho các biến được sử dụng nhiều như biến kiểm soát vòng lặp để nâng cao hiệu suất bằng cách giảm thiểu thời gian truy cập.thứ hai, bạn chỉ có thể sử dụng và chỉ đăng ký bộ lưu trữ trong tình huống này như, vui (tự động int a, auto int b): lỗi vui vẻ (đăng ký int a, đăng ký int b): chỉ quyền này sẽ chạy vui vẻ (tĩnh int a, static int b): lỗi vui vẻ (extern int a, extern int b): lỗi

+3

Cái gì ?! Văn bản K & R là từ những năm 1970, vì vậy một số đề xuất của họ đã lỗi thời một chút. Sử dụng 'register' chắc chắn là một trong số đó. –

4

Tôi biết điều này là từ một thời gian, nhưng đây là một triển khai thực hiện một subprocedure từ heapsort trong đó việc sử dụng đăng ký biến làm cho các thuật toán nhanh hơn, ít nhất là sử dụng gcc 4.5.2 để biên dịch mã

inline void max_heapify(int *H, int i){ 
    char OK = FALSE; 
    register int l, r, max, hI; 
    while(!OK){ 
     OK = TRUE; 
     l = left(i); 
     r = right(i); 
     max = i; 
     if(l <= H[SIZE] && H[l] > H[i]){ 
      max = l; 
     } 
     if(r <= H[SIZE] && H[r] > H[max]){ 
      max = r; 
     } 
     if(max != i){ 
      OK = FALSE; 
      hI = H[i]; 
      H[i] = H[max]; 
      H[max] = hI; 
      i = max; 
     } 
    } 
} 

tôi đã thử nghiệm algortihm với và w ithout từ khóa đăng ký trước khi các thuộc tính và thực hiện nó để sắp xếp một mảng ngẫu nhiên với 50.000.000 yếu tố trên máy tính xách tay của tôi, một vài lần cho mỗi phiên bản.

việc sử dụng thanh ghi đã giảm thời gian heapsort từ ~ 135 xuống ~ 125 giây.

Tôi cũng đã thử nghiệm chỉ với 5.000.000 phần tử, nhưng thực thi nó nhiều lần hơn.

Phiên bản mà không đăng ký bắt đầu lúc 11s nhưng từng thực hiện giảm thời gian cho đến khi nó đạt 9,65s và dừng lại ở đó

phiên bản với đăng ký bắt đầu lúc 10s và giảm thời gian cho đến khi 8,80s.

Tôi nghĩ rằng nó có liên quan đến bộ nhớ cache. Tuy nhiên có vẻ như các thanh ghi làm cho thuật toán nhanh hơn bằng hệ số constanct

Vì các biến này được sử dụng khá nhiều trong thuật toán, bằng cách đảm bảo chúng nằm trong thanh ghi thay vì để công việc này cho trình biên dịch dẫn đến kết quả tốt hơn trường hợp. Tuy nhiên, nó đã không cải thiện thời gian nhiều.

Hy vọng rằng sẽ rất hữu ích cho ai đó, lời chúc mừng.

+3

Để có điểm chuẩn nghiêm túc, bạn nên cung cấp thông tin về cách bạn biên dịch nó (cờ nào), nền tảng nào bạn đã làm và có lẽ một số chi tiết về kiến ​​trúc và/hoặc CPU của bạn. Cách bạn chạy max_heapify cũng rất quan trọng. – raylu

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