Là quản lý bộ nhớ trong lập trình đang trở thành một mối quan tâm không liên quan?
Quản lý bộ nhớ (hoặc kiểm soát) thực sự là lý do chính khiến tôi sử dụng C và C ++.
Bộ nhớ tương đối rẻ bây giờ.
Bộ nhớ không nhanh. Chúng tôi vẫn đang xem xét một số lượng nhỏ các thanh ghi, như bộ đệm dữ liệu 32KB cho L1 trên i7, 256KB cho L2 và 2MB cho L3 / lõi. Mà nói:
Nếu chúng ta không nói về các nền tảng đích với các giới hạn nghiêm ngặt về bộ nhớ làm việc (tức là các hệ thống nhúng và tương tự), thì việc sử dụng bộ nhớ có phải là mối quan tâm khi chọn ngôn ngữ cho mục đích chung hiện nay không?
Sử dụng bộ nhớ ở mức độ chung, có thể không. Tôi hơi không thực tế ở chỗ tôi không thích ý tưởng về một notepad, ví dụ, 50 megabyte DRAM và hàng trăm megabyte dung lượng ổ cứng, mặc dù tôi có rất nhiều thứ. Tôi đã ở đây được một thời gian dài và tôi cảm thấy kỳ lạ và khó hiểu khi thấy một ứng dụng đơn giản như vậy chiếm quá nhiều bộ nhớ cho những gì có thể thực hiện được với kilobyte. Điều đó nói rằng, tôi có thể sống với chính mình nếu tôi gặp phải một điều như vậy nếu nó vẫn tốt và đáp ứng.
Lý do quản lý bộ nhớ rất quan trọng đối với tôi trong lĩnh vực của mình là không làm giảm việc sử dụng bộ nhớ nói chung. Hàng trăm megabyte sử dụng bộ nhớ sẽ không nhất thiết làm chậm ứng dụng theo bất kỳ cách không tầm thường nào nếu không có bộ nhớ đó thường xuyên được truy cập (ví dụ: chỉ khi nhấp vào nút hoặc một số hình thức nhập khác của người dùng, cực kỳ không thường xuyên trừ khi bạn đang nói về những người chơi Starcraft Hàn Quốc có thể nhấp vào nút một triệu lần một giây).
Lý do quan trọng trong lĩnh vực của tôi là để bộ nhớ chặt chẽ và gần nhau thường xuyên được truy cập (ví dụ: được lặp qua từng khung hình) trong các đường dẫn quan trọng đó. Chúng tôi không muốn bỏ lỡ bộ nhớ cache mỗi lần chúng tôi truy cập chỉ một trong số một triệu phần tử cần được truy cập trong một vòng lặp mỗi khung hình. Khi chúng ta chuyển bộ nhớ xuống hệ thống phân cấp từ bộ nhớ chậm sang bộ nhớ nhanh trong các khối lớn, giả sử các dòng bộ đệm 64 byte, sẽ thực sự hữu ích nếu tất cả 64 byte đó đều chứa dữ liệu liên quan, nếu chúng ta có thể ghép nhiều phần tử dữ liệu vào 64 byte đó và nếu các mẫu truy cập của chúng tôi sao cho chúng tôi sử dụng tất cả trước khi dữ liệu bị đuổi.
Dữ liệu được truy cập thường xuyên cho hàng triệu phần tử chỉ có thể kéo dài 20 megabyte mặc dù chúng tôi có gigabyte. Nó vẫn tạo ra một thế giới khác biệt về tốc độ khung hình lặp lại trên dữ liệu đó mỗi khung hình được vẽ nếu bộ nhớ bị bó chặt và gần nhau để giảm thiểu lỗi bộ nhớ cache và đó là nơi quản lý / kiểm soát bộ nhớ rất hữu ích. Ví dụ trực quan đơn giản trên một hình cầu có vài triệu đỉnh:
Cái trên thực sự chậm hơn phiên bản có thể thay đổi của tôi vì nó đang thử nghiệm biểu diễn cấu trúc dữ liệu liên tục của lưới, nhưng với điều đó, tôi đã phải vật lộn để đạt được tốc độ khung hình như vậy ngay cả trên một nửa dữ liệu đó (phải thừa nhận rằng phần cứng đã nhanh hơn kể từ khi tôi vật lộn ) bởi vì tôi đã không hiểu được việc giảm thiểu lỗi bộ nhớ cache và sử dụng bộ nhớ cho dữ liệu lưới. Lưới là một số cấu trúc dữ liệu khó nhất mà tôi đã xử lý về vấn đề này vì chúng lưu trữ rất nhiều dữ liệu phụ thuộc lẫn nhau phải giữ đồng bộ như đa giác, cạnh, đỉnh, như nhiều bản đồ kết cấu mà người dùng muốn đính kèm, trọng lượng xương, bản đồ màu, bộ lựa chọn, mục tiêu hình thái, trọng lượng cạnh, vật liệu đa giác, v.v.
Tôi đã thiết kế và triển khai một số hệ thống lưới trong vài thập kỷ qua và tốc độ của chúng thường tỷ lệ thuận với việc sử dụng bộ nhớ của chúng. Mặc dù tôi đang làm việc với rất nhiều bộ nhớ so với khi tôi bắt đầu, các hệ thống lưới mới của tôi nhanh hơn 10 lần so với thiết kế đầu tiên của tôi (gần 20 năm trước) và ở mức độ lớn vì chúng sử dụng khoảng 1/10 kí ức. Phiên bản mới nhất thậm chí sử dụng nén được lập chỉ mục để nhồi nhét càng nhiều dữ liệu càng tốt và mặc dù có quá trình xử lý giải nén, việc nén thực sự cải thiện hiệu năng bởi vì, một lần nữa, chúng ta có rất ít bộ nhớ nhanh quý giá. Bây giờ tôi có thể điều chỉnh một triệu lưới đa giác với tọa độ kết cấu, nếp gấp cạnh, gán vật liệu, v.v. cùng với chỉ số không gian cho nó trong khoảng 30 megabyte.
Đây là nguyên mẫu có thể thay đổi với hơn 8 triệu hình tứ giác và sơ đồ phân chia nhiều điểm trên i3 với GF 8400 (đây là từ một vài năm trước). Nó nhanh hơn phiên bản bất biến của tôi nhưng không được sử dụng trong sản xuất vì tôi đã tìm thấy phiên bản bất biến nên dễ bảo trì hơn rất nhiều và hiệu suất đạt được không quá tệ. Lưu ý rằng khung dây không chỉ ra các mặt, nhưng các miếng vá (dây thực sự là các đường cong, nếu không thì toàn bộ lưới sẽ có màu đen đặc), mặc dù tất cả các điểm trong một mặt đều được sửa đổi bằng cọ.
Vì vậy, dù sao, tôi chỉ muốn trình bày một số điều ở trên để hiển thị một số ví dụ cụ thể và các lĩnh vực nơi quản lý bộ nhớ rất hữu ích và cũng hy vọng mọi người không nghĩ rằng tôi chỉ nói ra khỏi mông mình. Tôi có xu hướng hơi khó chịu khi mọi người nói rằng bộ nhớ rất phong phú và rẻ tiền, bởi vì đó là nói về bộ nhớ chậm như DRAM và ổ cứng. Nó vẫn còn rất nhỏ và rất quý giá khi chúng ta nói về bộ nhớ nhanh và hiệu suất cho các đường dẫn thực sự quan trọng (nghĩa là thông thường, không phải cho tất cả mọi thứ) liên quan đến việc chơi với số lượng bộ nhớ nhanh nhỏ đó và sử dụng nó hiệu quả nhất có thể .
Đối với loại điều này, thật sự hữu ích khi làm việc với một ngôn ngữ cho phép bạn thiết kế các đối tượng cấp cao như C ++, trong khi vẫn có thể lưu trữ các đối tượng này trong một hoặc nhiều mảng liền kề với sự đảm bảo rằng bộ nhớ của tất cả các đối tượng như vậy sẽ được biểu diễn liên tục và không có bất kỳ chi phí bộ nhớ không cần thiết nào cho mỗi đối tượng (ví dụ: không phải tất cả các đối tượng đều cần phản xạ hoặc gửi ảo). Khi bạn thực sự di chuyển vào các khu vực quan trọng về hiệu năng, nó thực sự trở thành một sự tăng năng suất để kiểm soát bộ nhớ như vậy, nói đùa với các nhóm đối tượng và sử dụng các loại dữ liệu nguyên thủy để tránh chi phí đối tượng, chi phí GC và để bộ nhớ được truy cập thường xuyên Tiếp giáp nhau.
Vì vậy, quản lý / kiểm soát bộ nhớ (hoặc thiếu nó) thực sự là một lý do chi phối trong trường hợp của tôi vì chọn ngôn ngữ nào hiệu quả nhất cho phép tôi giải quyết vấn đề. Tôi chắc chắn viết phần mã của mình không quan trọng về hiệu năng và vì thế tôi có xu hướng sử dụng Lua, thứ khá dễ nhúng từ C.