Gần đây tôi đã được biết về các chức năng tích hợp của GCC đối với một số chức năng quản lý bộ nhớ của thư viện C, cụ thể là __builtin_malloc()
và các phần tích hợp có liên quan (xem https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html). Sau khi tìm hiểu về __builtin_malloc()
, tôi đã tự hỏi làm thế nào nó có thể làm việc để cung cấp cải tiến hiệu suất trên các thói quen thư viện liên quan malloc()
đồng bằng. Ví dụ, nếu hàm thành công, nó phải cung cấp một khối có thể được giải phóng bằng một cuộc gọi đến số free()
đơn giản vì con trỏ có thể được giải phóng bởi một mô-đun được biên dịch mà không cần bật __builtin_malloc()
hoặc __builtin_free()
(hoặc tôi có sai không về điều này và nếu sử dụng __builtin_malloc()
, nội dung dựng sẵn phải được sử dụng trên toàn cầu?). Do đó đối tượng được phân bổ phải là một thứ có thể được quản lý với các cấu trúc dữ liệu đơn giản là hợp đồng với malloc()
và free()
.Những cải tiến nào của `__builtin_malloc()` của GCC cung cấp trên `malloc() đơn giản`?
Tôi không thể tìm thấy bất kỳ chi tiết nào về cách hoạt động của __builtin_malloc()
hoặc chính xác (tôi không phải là người biên dịch trình biên dịch, vì vậy việc chuyển qua mã nguồn GCC không có trong buồng lái của tôi). Trong một số thử nghiệm đơn giản, nơi tôi đã cố gắng gọi trực tiếp __builtin_malloc()
, nó chỉ đơn giản là kết thúc được phát ra trong mã đối tượng như một cuộc gọi đến đồng bằng malloc()
. Tuy nhiên, có thể có chi tiết tinh tế hoặc nền tảng mà tôi không cung cấp trong các thử nghiệm đơn giản này.
Những loại cải tiến hiệu suất nào có thể __builtin_malloc()
cung cấp cuộc gọi đến số malloc()
đơn giản? Liệu __builtin_malloc()
có phụ thuộc vào cấu trúc dữ liệu khá phức tạp mà việc sử dụng thực thi malloc()
của glibc không? Hoặc ngược lại, số malloc()
/free()
của glibc có một số mã để xử lý các khối có thể được phân bổ bởi __builtin_malloc()
không?
Về cơ bản, nó hoạt động như thế nào?
Lời giải thích thú vị và hữu ích. Vì vậy, tính năng thiết yếu của phiên bản tích hợp là nó có thể đảm bảo một hành vi đã biết cho trình biên dịch, cho phép nó được tối ưu hóa, và có lẽ để nhận các tối ưu hóa khác ... –
@DanLenski Đó là cách tôi nhìn thấy nó. Sau một số thí nghiệm, điều duy nhất tôi có thể khiến GCC làm "đặc biệt" với '__builtin_malloc' là tối ưu hóa nó. Tôi đã thử truyền nó '0', nhưng chuyển kết quả tới hàm khác (bên ngoài) đã gây ra một lệnh gọi' malloc' được phát ra. –
Trình biên dịch có thể biết rằng kết quả của __builtin_malloc không bí danh với bất kỳ con trỏ nào khác. Giả sử hàm của bạn có int * p làm tham số và gọi int * q = malloc (sizeof int); * q = 1; sau đó trình biên dịch biết rằng nhiệm vụ này đã không sửa đổi * p. – gnasher729