Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 13 kết quả

Đề tài: tác dụng của từ khóa restrict ?

  1. #1
    Ngày gia nhập
    07 2010
    Nơi ở
    chỗ kín
    Bài viết
    446

    Mặc định tác dụng của từ khóa restrict ?

    các pro cho em hỏi từ khóa __restrict trong C hay là C++ có tác dụng gì, em đọc mấy bài trên mạng mà em thấy khó hiểu quá.
    //Em dùng VS trên windows
    Thanks.

  2. #2
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Bạn tham khảo đề tài đã được đưa ra từ trước tại: Từ khóa restrict trong chuẩn C99 có tác dụng gì

    Nói một cách đơn giản là khi khai báo có thêm từ khóa restrict biến đó sẽ không align. Bạn hiểu về align thì sẽ hiểu được restrict thôi.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  3. #3
    Ngày gia nhập
    07 2010
    Nơi ở
    chỗ kín
    Bài viết
    446

    ok, thanks anh.


    anh sửa lại cái ví dụ này đi:
    (code này của anh ở cái link)
    Code:
    int n = 3;
    int* restrict a1;
    int* restrict a2;
    int* t = malloc(2 * n * sizeof(int));
    a1 = t; // nửa đầu của t
    a2 = t + n; // nửa sau của t
    có restrict hay ko có đều sinh ra cùng một mã asm, ví dụ này không có tác dụng.

  4. #4
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Ặc ặc mình vẫn hiểu từ khóa restrict là anti-alias chứ nhỉ :( sao lại liên quan đến align ở đây
    Nhưng đúng là nó không có nhiều tác dụng và hầu như không bao giờ gặp nên tốt nhất là không quan tâm vội

    Mình giải thích tạm theo cách mình hiểu nhé (sai sót các bạn góp ý giúp mình). Đầu tiên mình giải thích khái niệm alias:
    Giả sử mình có 2 mảng a, b kiểu int[10] và 1 hàm inverse(b, a) gán b là mảng thứ tự ngược của a
    vậy, trong trường hợp biết a và b là 2 mảng độc lập (no-alias) thì bạn có thể for i = 0->9: b[i] = a[9 - i]
    Nhưng khi bạn gọi inverse(a, a) sẽ sai!!! vì trường hợp này a và b không độc lập (alias)
    Vậy khi implement hàm inverse này, nếu bạn biết a và b là no-alias thì sẽ dễ dàng và hiệu quả hơn

    Tương tự, khi khai báo 1 poiner là restricted thì compiler sẽ biết vùng nhớ được pointer đó trỏ đến hoàn toàn độc lập, không chồng chéo gì đến vùng nhớ khác (no-alias) ==> trong 1 số trường hợp compiler sẽ có thể dịch ra code tối ưu hơn. Nhưng những trường hợp nào tối ưu được hơn thì mình chịu có vẻ rất ít, hoặc là 1 tính năng dự phòng cho tương lai là chính

    Edit: viết xong mới google, thấy ví dụ để compiler có thể dịch được code tốt hơn nè:
    http://en.wikipedia.org/wiki/Restrict
    Đã được chỉnh sửa lần cuối bởi fbchicken : 04-08-2011 lúc 11:39 PM.

  5. #5
    Ngày gia nhập
    07 2010
    Nơi ở
    chỗ kín
    Bài viết
    446

    ok, thank you. Nhưng cho mình hỏi thêm một câu nữa : tham số truyền vào hàm inverse thực chất là một con trỏ, nhưng không biết kích thước vùng dữ liệu, làm sao trình dịch biết 2 con trỏ có chồng lên nhau không.

  6. #6
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Mặc định tác dụng của từ khóa restrict ?

    Trích dẫn Nguyên bản được gửi bởi pkthanh92 Xem bài viết
    ok, thank you. Nhưng cho mình hỏi thêm một câu nữa : tham số truyền vào hàm inverse thực chất là một con trỏ, nhưng không biết kích thước vùng dữ liệu, làm sao trình dịch biết 2 con trỏ có chồng lên nhau không.
    Trình dịch đương nhiên không biết! Nhưng khi mình khai báo 1 con trỏ là restrict, tức là mình báo cho trình dịch: trong toàn bộ vùng sử dụng của nó, không bị dữ liệu nào khác chồng lên mà có thể ảnh hưởng đến kết quả (và mình phải đảm bảo điều đó).

  7. #7
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    @pkthanh92:
    - restrict không có tác dụng nếu không phải là chuẩn C99
    - Trong VC++ là __restrict
    - Trong gcc là __restrict__

    @fbchicken: Cảm ơn bạn, ở trên mình viết nhầm. Nhưng bạn đã viết rõ ràng rồi mình không cần sửa lại.

    -----------------------------
    Còn một đặc điểm của restrict là: Không có con trỏ khác restrict có thể truy cập vào vùng nhớ được trỏ đến bởi restrict. Nghĩa là nếu đã vùng nhớ đã được trỏ bởi con trỏ restrict thì các con trỏ loại khác sẽ không thể truy cập.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  8. #8
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Trích dẫn Nguyên bản được gửi bởi Kevin Hoang Xem bài viết
    Còn một đặc điểm của restrict là: Không có con trỏ khác restrict có thể truy cập vào vùng nhớ được trỏ đến bởi restrict. Nghĩa là nếu đã vùng nhớ đã được trỏ bởi con trỏ restrict thì các con trỏ loại khác sẽ không thể truy cập.
    Mình chưa biết tính chất này. Vừa test thử trên gcc thì thấy 2 con trỏ, 1 restrict 1 không, cùng trỏ đến 1 địa chỉ, vẫn đọc/ghi bình thường

    Nhưng thôi, mình cũng không quan tâm vì có vẻ nó ít ứng dụng!
    Cũng gặp qua 1 vài thư viện có sử dụng từ khóa này nhưng rất ít. Với cả, mình sử dụng những thư viện đó cũng chẳng cần quan tâm nó implement thế nào
    Dự đoán cả đời chưa chắc đã viết 1 đoạn code nào cần dùng restrict để tối ưu hóa cả. hihi.

  9. #9
    Ngày gia nhập
    07 2010
    Nơi ở
    chỗ kín
    Bài viết
    446

    (dịch lại wiki)
    khi khai báo một hàm có 2 tham số là con trỏ restrict, thì trình biên dịch coi như 2 con trỏ đó không trỏ cùng một đối tượng. Code sinh ra sẽ ngắn hơn -> nhanh hơn.

    em làm thử một ví dụ trên VS thế này.

    so sánh kết quả:
    Visual C++ Code:
    1. #include <stdio.h>
    2. #include <conio.h>
    3.  
    4. void foo1(unsigned long* pa, unsigned long* pb, unsigned long* pc)
    5. {
    6.     *pa+= *pc;
    7.     *pb+= *pc;
    8. }
    9.  
    10. void foo2(unsigned long* __restrict pa, unsigned long* __restrict pb, unsigned long* __restrict pc)
    11. {
    12.     *pa+= *pc;
    13.     *pb+= *pc;
    14. }
    15.  
    16. int main()
    17. {
    18.     unsigned long a, b, *c;
    19.     c = &a;
    20.     a = 2;
    21.     b = 1;
    22.     foo1( &a, &b, c );
    23.     printf( "\na= %d ; b = %d ", a, b );
    24.  
    25.     a = 2;
    26.     b = 1;
    27.     foo2( &a, &b, c );
    28.         // viết foo2( &a, &b, &a ) thì thô thiển quá, sợ trình dịch nó xóa mất, dùng thông qua biến c cho chắc ăn
    29.     printf( "\na= %d ; b = %d ", a, b );
    30.     return 0;
    31. }

    output:
    Code:
    a= 4 ; b = 5
    a= 4 ; b = 5
    đầu tiên là phát hiện ra lỗi của diễn đàn không bôi đen từ __restrict
    sau đó là nếu cứ theo lý thyết trên thì phải ra 2 kết quả khác nhau ( vì khi gọi foo2, chạy đến dòng *pb+= *pc; thì comiler không cần tham chiếu đến ô nhớ trong pc mà lấy luôn giá trị *pc trước đó).

    đo thời gian

    Visual C++ Code:
    1. #include <Windows.h>
    2. #include <stdio.h>
    3. #include <conio.h>
    4.  
    5. void foo1(unsigned long* pa, unsigned long* pb, unsigned long* pc)
    6. {
    7.     *pa+= *pc;
    8.     *pb+= *pc;
    9. }
    10.  
    11. void foo2(unsigned long* __restrict pa, unsigned long* __restrict pb, unsigned long* __restrict pc)
    12. {
    13.     *pa+= *pc;
    14.     *pb+= *pc;
    15. }
    16.  
    17. int main()
    18. {
    19.     DWORD dT, i, j;
    20.     unsigned long a, b, *c;
    21.     c = &a;
    22.    
    23.     printf( "\nnormal - restrict ");
    24.     for( j = 0; j < 10; j++)
    25.     {
    26.         a = 1;
    27.         b = 0;
    28.         dT = GetTickCount();
    29.         for( i = 0; i < 500000; i++)    foo1( &a, &b, c );
    30.         dT = GetTickCount() - dT;
    31.         printf( "\n  %d   - ", dT );
    32.  
    33.         a = 1;
    34.         b = 0;
    35.         dT = GetTickCount();
    36.         for( i = 0; i < 500000; i++)    foo2( &a, &b, c );
    37.  
    38.         dT = GetTickCount() - dT;
    39.         printf( "   %d", dT );
    40.     }
    41.     _getch();
    42.     return 0;
    43. }


    output:
    Code:
    normal - restrict
      16    -   16
      15    -   31
      16    -   16
      15    -   16
      15    -   16
      16    -   15
      16    -   15
      16    -   16
      0    -   15
      31    -   16
    -> coi như bằng nhau

    ai giải thích dùm em với, sao 2 test ở trên lại ko đúng theo lý thuyết vậy, thanks.

  10. #10
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Có mấy điều như sau:
    1. Dùng clock của windows để đo performance, với giá trị in ra < 20 đều coi như vô nghĩa. (google gettickcount precision accuracy để hiểu rõ hơn) Bạn có thể dùng CPU clock (google lệnh rdtsc), hoặc dùng linux, hoặc tăng số vòng lặp để đạt hiệu số clock ít nhất vài trăm.
    2. Do windows không real-time nên đo đạc sẽ bị sai số nhất định, phụ thuộc rất nhiều vào điều kiện thời tiết
    3. Lợi ích đạt được (1 CPU instruction) sẽ không thấy được khi trong cùng vòng lặp có quá nhiều CPU instruction khác (inc i, compare, function call - đặc biệt chi phí cho function call rất cao). Muốn thể hiện được lợi ích của restrict thì bạn phải đảm bảo function được inline. Nói chung để đo những cái tương tự, bạn nên chạy 1 lần (function inline) và dùng asm + lệnh rdtsc để đo số CPU clock là ổn nhất

    4. 1 số compiler trực tiếp bỏ qua từ khóa restrict, tức là coi như nó không tồn tại Bạn google xem VC++ xử lý từ khóa đó thế nào. Với hiện tượng 2 kết quả như nhau thì có vẻ VC++ cũng bỏ qua rồi
    Đã được chỉnh sửa lần cuối bởi fbchicken : 10-08-2011 lúc 02:23 AM.

Các đề tài tương tự

  1. Tìm 1 khóa và mọi khóa của lược đồ quan hệ viết bằng VC++ (MFC Source code)
    Gửi bởi gianghoplus trong diễn đàn Dự án & Source code VC++
    Trả lời: 6
    Bài viết cuối: 11-04-2016, 03:25 PM
  2. Siêu thị khóa cửa cung cấp các loại khóa cửa cao cấp và an toàn
    Gửi bởi vinastyle trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 20-09-2013, 09:10 AM
  3. Đưa khóa vào cây nhị phân tìm kiếm, biểu diễn khi có 2 khóa trùng nhau như thế nào?
    Gửi bởi bubu333 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 1
    Bài viết cuối: 26-08-2011, 08:57 AM
  4. Từ khóa restrict trong chuẩn C99 có nghĩa là gì?
    Gửi bởi haian trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 2
    Bài viết cuối: 16-07-2011, 11:55 AM
  5. Tạo 1 khóa và chỉnh sữa khóa trong regedit, secpol và gpedit
    Gửi bởi azurelonely trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 5
    Bài viết cuối: 01-06-2011, 08:43 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn