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?


38

Bối cảnh
Tôi đã xem lại một trang web cũ (nhưng tuyệt vời) mà tôi chưa từng đến từ lâu - Cuộc thi bắn súng ngôn ngữ Alioth ( http://benchmarkgame.alioth.debian.org/ ).

Tôi đã bắt đầu lập trình trong C / C ++ vài năm trước, nhưng từ đó đã hoạt động gần như độc quyền với Java do những hạn chế về ngôn ngữ trong các dự án mà tôi đã tham gia. Không nhớ các số liệu, tôi muốn thấy, xấp xỉ, Java tốt như thế nào chống lại C / C ++ về mặt sử dụng tài nguyên.

Thời gian thực hiện vẫn tương đối tốt, với Java hoạt động kém nhất là chậm hơn 4x so với C / C ++, nhưng trung bình khoảng (hoặc thấp hơn) 2x. Do bản chất của việc triển khai Java, điều này không có gì đáng ngạc nhiên và thời gian thực hiện của nó thực sự thấp hơn những gì tôi mong đợi.

Viên gạch thực sự là phân bổ bộ nhớ - tệ nhất là Java được phân bổ:

  • bộ nhớ lớn hơn 52 lần so với C
  • và gấp 25 lần so với C ++.

Bộ nhớ 52x ... Hoàn toàn khó chịu, phải không? ... hoặc là nó? Bộ nhớ tương đối rẻ bây giờ.

Câu hỏi:
Nếu chúng ta không nói về các nền tảng đích 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?

Tôi đang hỏi một phần vì tôi đang xem xét việc chuyển sang Scala như ngôn ngữ chính của mình. Tôi rất thích các khía cạnh chức năng của nó, nhưng từ những gì tôi có thể thấy nó thậm chí còn đắt hơn về mặt bộ nhớ so với Java. Tuy nhiên, do bộ nhớ dường như ngày càng nhanh hơn, rẻ hơn và dồi dào hơn theo năm (dường như ngày càng khó tìm thấy một máy tính xách tay tiêu dùng mà không có ít nhất 4GB RAM DDR3), có thể không tranh luận rằng việc quản lý tài nguyên đang ngày càng trở nên nhiều hơn không liên quan so với các tính năng ngôn ngữ cấp cao (có thể đắt tiền thực hiện) cho phép xây dựng nhanh hơn các giải pháp dễ đọc hơn?


32
Đừng quên rằng chỉ vì Java phân bổ bộ nhớ nhiều hơn 52 lần so với C cho một điểm chuẩn nhỏ, điều đó không có nghĩa là nó sẽ sử dụng bộ nhớ nhiều hơn 52 lần cho một ứng dụng lớn. Phần chia sẻ của bộ nhớ đó sẽ là một lượng cố định theo yêu cầu của JVM và ứng dụng của bạn càng lớn thì phần đó sẽ càng ít quan trọng.
Carson63000

4
Nếu phát triển di động là không liên quan, hơn có.
JeffO

3
Câu hỏi đặt ra là điểm chuẩn của Java so với C / C ++ tệ đến mức nào và điều đó có nghĩa gì trong việc lựa chọn giữa hai ngôn ngữ. Tôi thấy đây là chủ đề, phù hợp với tất cả các lập trình viên, rõ ràng, tập trung và có thể được trả lời hợp lý ở dạng hiện tại. Tôi đã bỏ phiếu để mở lại.
GlenPeterson

Hầu hết các vấn đề về hiệu suất được gây ra và cố định ở cấp thiết kế, không phải ở cấp công cụ. Một số vấn đề cần độ chi tiết 1ms và do đó cần C / C ++. Nếu bạn có thời gian rảnh, như 10ms, thì có lẽ Scala hoặc Java là một lựa chọn tốt. Hầu hết các bộ điều khiển đầu vào cho các trò chơi hoạt động ở mức 50-100ms. Nhiều người ngày nay viết các phần quan trọng bằng một ngôn ngữ và phần còn lại của một chương trình bằng ngôn ngữ khác.
GlenPeterson

4
Khi xem xét "25 lần nhiều hơn C ++" trong bài kiểm tra này, người ta cần tính đến việc bổ sung liên tục thời gian chạy (khoảng 13 Mb). Khi vấn đề trở nên lớn hơn, yêu cầu bộ nhớ thời gian chạy trở nên ít hơn theo tỷ lệ phần trăm của toàn bộ chương trình. Trong đó mức sử dụng bộ nhớ C ++ nhỏ hơn 1 MB, nếu bạn trừ đi mức sử dụng bộ nhớ C ++ khỏi mức sử dụng Bộ nhớ Java, bạn sẽ nhận được một giá trị khá không đổi.

Câu trả lời:


34

Quản lý bộ nhớ hoàn toàn phù hợp vì nó chi phối tốc độ của một thứ gì đó xuất hiện ngay cả khi thứ đó có bộ nhớ lớn. Ví dụ tốt nhất và kinh điển nhất là các trò chơi có tiêu đề AAA như Call of Duty hoặc Bioshock. Đây là những ứng dụng thời gian thực hiệu quả đòi hỏi số lượng kiểm soát lớn về mặt tối ưu hóa và sử dụng. Đó không phải là vấn đề sử dụng mà là vấn đề quản lý.

Nó đi xuống hai từ: Bộ sưu tập rác. Các thuật toán thu gom rác có thể gây ra các trục trặc nhẹ trong hiệu suất hoặc thậm chí khiến ứng dụng bị treo trong một hoặc hai giây. Hầu như vô hại trong một ứng dụng kế toán nhưng có khả năng hủy hoại về trải nghiệm người dùng trong trò chơi Call of Duty. Do đó, trong các ứng dụng có vấn đề về thời gian, rác ngôn ngữ được thu thập có thể cực kỳ có vấn đề. Chẳng hạn, đây là một trong những mục tiêu thiết kế của Squirrel, nhằm tìm cách khắc phục vấn đề mà Lua gặp phải với GC của mình bằng cách sử dụng tính năng tham chiếu thay thế.

Có phải là đau đầu hơn? Chắc chắn nhưng nếu bạn cần kiểm soát chính xác, bạn đưa ra nó.


14
-1 "... thực sự gây chết người trong một trò chơi ..." - Công việc hàng ngày của tôi là một hệ thống quan trọng về an toàn như an toàn tính mạng. Điều tồi tệ nhất xảy ra trong phần mềm trò chơi là người viết bị phá sản vì sự nhảm nhí của nó và không ai mua nó. Đây là một sự khác biệt không nên tầm thường hóa.
mattnz

4
@mattnz Lựa chọn từ ngữ kém về phía tôi. Nó đã được sửa chữa. Đó không phải là ý định của tôi để tầm thường hóa bất cứ điều gì.
Kỹ sư thế giới

19
@Mattnz: Nếu bạn quen thuộc với các trò chơi, rõ ràng anh ta có nghĩa là nó có thể gây chết người cho nhân vật của bạn , đó là một tuyên bố hoàn toàn đúng.
Mason Wheeler

8
+1 vì người trả lời có kim cương nên câu trả lời phải đúng.
psr

8
Người thu gom rác thời gian thực đã tồn tại từ lâu đời.
Jörg W Mittag

30

Viên gạch thực sự là sự phân bổ bộ nhớ - tệ nhất, Java đã phân bổ bộ nhớ lớn hơn 52 lần so với C và 25 lần so với C ++.

Bạn có hiểu những con số bạn dựa trên câu hỏi của bạn?

  • Bao nhiêu bộ nhớ đã được phân bổ?
  • Các chương trình đang làm gì?

Khi có sự chênh lệch lớn giữa các chương trình Java và C đó, thì chủ yếu là phân bổ bộ nhớ JVM mặc định so với bất kỳ nhu cầu libc nào:


  • Chương trình Java n-body 13.996KB :: Chương trình C 320KB :: Pascal 8KB miễn phí

Xem xét các tác vụ yêu cầu bộ nhớ được phân bổ (hoặc sử dụng bộ đệm bổ sung để tích lũy kết quả từ các chương trình đa lõi):

  • Mandelbrot
    chương trình Java 67 , chương trình 880KB :: C 30 , 444KB


  • chương trình Java k-nucleotide 494 , 040KB :: chương trình C 153 , 452KB


  • chương trình Java bổ sung ngược 511 , 484KB :: Chương trình C 248 , 632KB


  • chương trình Java regex-dna 557 , 080KB :: chương trình C 289 , 088KB


  • chương trình Java cây nhị phân 506 , 592KB :: chương trình C 99 , 448KB

... 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?

Nó phụ thuộc vào việc sử dụng cụ thể , cho cách tiếp cận cụ thể của bạn để giải quyết các vấn đề cụ thể bạn cần giải quyết, sẽ bị hạn chế bởi các giới hạn cụ thể của bộ nhớ khả dụng trên nền tảng cụ thể sẽ được sử dụng.


3
Quan điểm của bạn về việc đào sâu vào các con số là hợp lệ và trang web đó chắc chắn có khá nhiều lời từ chối xung quanh các bài kiểm tra của họ. Câu trả lời của bạn sẽ được củng cố bằng cách trực tiếp giải quyết câu hỏi cốt lõi, đó là "việc sử dụng bộ nhớ có phải là một mối quan tâm không?"

1
Câu trả lời tuyệt vời mà câu trả lời tương đối kém ( điểm chuẩn được chỉ định mơ hồ thậm chí còn tồi tệ hơn so với tối ưu hóa sớm :). Dữ liệu hỗ trợ phân tích được trình bày tốt, cụ thể và làm cho một thực phẩm tuyệt vời cho suy nghĩ. Chắc chắn giá trị một tiền thưởng "câu trả lời mẫu mực" .
gnat

17

Như với tất cả mọi thứ, đó là một sự đánh đổi.

Nếu bạn đang xây dựng một ứng dụng sẽ chạy trên một máy tính để bàn duy nhất và có thể dự kiến ​​sẽ kiểm soát một phần lớn RAM trên máy đó, thì có thể đáng để hy sinh việc sử dụng bộ nhớ cho tốc độ thực hiện. Nếu bạn đang nhắm mục tiêu vào cùng một máy nhưng bạn đang xây dựng một tiện ích nhỏ sẽ cạnh tranh với một loạt các ứng dụng ngốn bộ nhớ khác đang chạy đồng thời, bạn có thể muốn thận trọng hơn về sự đánh đổi đó. Một người dùng có thể ổn với một trò chơi muốn có tất cả bộ nhớ của họ khi nó chạy (mặc dù, như World Engineering chỉ ra, họ ' sẽ lo ngại nếu người dọn rác quyết định tạm dừng hành động để quét) - họ có thể sẽ ít bị mê hoặc hơn nếu trình phát nhạc họ chạy trong nền trong khi làm những việc khác quyết định ngấu nghiến hàng tấn bộ nhớ và can thiệp vào khả năng làm việc của họ. Nếu bạn đang xây dựng một ứng dụng dựa trên web, bất kỳ bộ nhớ nào bạn sử dụng trên các máy chủ đều hạn chế khả năng mở rộng của bạn buộc bạn phải chi nhiều tiền hơn cho nhiều máy chủ ứng dụng hơn để hỗ trợ cùng một nhóm người dùng. Điều đó có thể có một tác động lớn đến kinh tế của công ty vì vậy bạn có thể muốn rất thận trọng khi thực hiện sự đánh đổi đó. bất kỳ bộ nhớ nào bạn sử dụng trên các máy chủ đều giới hạn khả năng mở rộng của bạn buộc bạn phải chi nhiều tiền hơn cho nhiều máy chủ ứng dụng hơn để hỗ trợ cùng một nhóm người dùng. Điều đó có thể có một tác động lớn đến kinh tế của công ty vì vậy bạn có thể muốn rất thận trọng khi thực hiện sự đánh đổi đó. bất kỳ bộ nhớ nào bạn sử dụng trên các máy chủ đều giới hạn khả năng mở rộng của bạn buộc bạn phải chi nhiều tiền hơn cho nhiều máy chủ ứng dụng hơn để hỗ trợ cùng một nhóm người dùng. Điều đó có thể có một tác động lớn đến kinh tế của công ty vì vậy bạn có thể muốn rất thận trọng khi thực hiện sự đánh đổi đó.


8

Nó phụ thuộc vào một số yếu tố, đặc biệt là quy mô mà bạn đang làm việc.

Chỉ để tranh luận, hãy giả sử chênh lệch 30 lần về bộ nhớ và 2 lần sử dụng CPU.

Nếu bạn đang xử lý một chương trình tương tác sẽ chiếm 10 megabyte bộ nhớ và 1 mili giây CPU nếu được viết bằng C, thì điều đó không quan trọng lắm - 300 megabyte bộ nhớ và 2 mili giây để thực thi thường hoàn toàn không liên quan trên máy tính để bàn thông thường, và không có nghĩa là nhiều ngay cả trên điện thoại hoặc máy tính bảng.

Sự khác biệt giữa việc cần khoảng một nửa tài nguyên của 1 máy chủ và cần 15 máy chủ là một bước lớn hơn nhiều - đặc biệt là khi nhân rộng ra 15 máy chủ có thể sẽ cần nhiều công việc phụ để phát triển thay vì ít hơn. Về khả năng mở rộng trong tương lai, các yếu tố tương tự mà bạn đề cập có xu hướng đề xuất rằng trừ khi cơ sở khách hàng của bạn trải qua sự tăng trưởng lớn , nếu bây giờ nó sẽ chạy trên một máy chủ, thì rất có thể khi bạn phát triển nhanh máy chủ đó, bạn sẽ có thể thay thế điều đó bằng một máy chủ mới hơn mà không gặp vấn đề gì.

Yếu tố khác bạn thực sự cần xem xét là chính xác có bao nhiêu sự khác biệt trong chi phí phát triển mà bạn sẽ thấy cho nhiệm vụ cụ thể của mình. Ngay bây giờ, về cơ bản, bạn đang nhìn vào một phía của một phương trình. Để có được một ý tưởng tốt về chi phí so với lợi ích, bạn (rõ ràng là đủ) cần phải xem xét cả chi phí và lợi ích, không chỉ riêng lẻ. Câu hỏi thực sự về cơ bản là: "x có lớn hơn y không?" - nhưng bạn không thể xác định điều đó bằng cách chỉ nhìn vào x. Bạn rõ ràng cần phải nhìn vào y là tốt.


2
+1 cho ghi chú tỷ lệ. Hãy xem bài viết này để thực sự đánh giá cao quản lý tài nguyên ở quy mô lớn.
Guy Coder

6

Quản lý bộ nhớ là hoàn toàn có liên quan trong thế giới ngày nay. Tuy nhiên, không phải theo cách bạn có thể mong đợi. Ngay cả trong các ngôn ngữ được thu thập rác, bạn phải đảm bảo bạn không bị rò rỉ tài liệu tham khảo

Bạn đang làm gì đó sai nếu đây là mã của bạn:

static List<string> Cache;

...
Cache.Add(foo); //and then never remove anything from Cache

Bộ sưu tập rác không thể biết một cách kỳ diệu bạn sẽ không bao giờ sử dụng một số tài liệu tham khảo nữa trừ khi bạn làm nó để bạn không thể sử dụng lại, tức là bằng cách đó Cache=null, bạn cảnh báo một cách hiệu quả cho người thu gom rác rằng "này tôi sẽ không thể truy cập nó nữa. Làm những gì bạn muốn với nó "

Nó phức tạp hơn thế, nhưng rò rỉ tham chiếu cũng giống như, nếu không, có hại hơn so với rò rỉ bộ nhớ truyền thống.

Cũng có một số nơi bạn không thể lắp bộ thu gom rác vào. Chẳng hạn, ATTiny84 là một vi điều khiển có 512 byte mã ROM và 32 byte RAM. Chúc may mắn! Đó là một cực đoan, và có lẽ sẽ không được lập trình trong bất cứ điều gì ngoài lắp ráp, nhưng vẫn còn. Các trường hợp khác bạn có thể có 1M bộ nhớ. Chắc chắn, bạn có thể phù hợp với một bộ thu rác, nhưng nếu bộ vi xử lý là rất chậm (hoặc bằng cách hạn chế, hoặc để bảo tồn pin), sau đó bạn sẽ không muốn sử dụng một bộ thu rác gây ra đó là quá đắt theo dõi những gì một lập trình viên có thể biết .

Việc sử dụng bộ sưu tập rác cũng trở nên khó khăn hơn đáng kể khi bạn cần thời gian phản hồi được đảm bảo. Giống như, nếu bạn có một màn hình trái tim hoặc một cái gì đó và khi nó nhận được 1trên một cổng nào đó, bạn cần đảm bảo rằng bạn có thể phản hồi nó với một tín hiệu thích hợp hoặc một cái gì đó trong vòng 10ms. Nếu ở giữa thói quen trả lời của bạn, người dọn rác cần phải vượt qua và cuối cùng phải mất 100ms để trả lời, đó có thể là một người đã chết. Thu gom rác rất khó, nếu không nói là không thể sử dụng khi cần đảm bảo thời gian.

Và tất nhiên, ngay cả trên phần cứng hiện đại, có một số trường hợp bạn cần thêm 2% hiệu suất bằng cách không lo lắng về chi phí hoạt động của bộ thu gom rác.


3

Như Donald Knuth đã nói, tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Trừ khi bạn có lý do để tin rằng bộ nhớ sẽ là nút cổ chai, đừng lo lắng về điều đó. Và cho rằng luật của Moore vẫn đang cung cấp dung lượng bộ nhớ tăng (mặc dù chúng tôi không nhận được mã đơn luồng nhanh hơn), có nhiều lý do để tin rằng trong tương lai chúng tôi sẽ ít bị hạn chế hơn về bộ nhớ so với chúng tôi là hôm nay

Điều đó nói rằng, nếu tối ưu hóa không sớm, bằng mọi cách hãy làm điều đó. Hiện tại tôi đang làm việc trong một dự án, nơi tôi hiểu rất rõ việc sử dụng bộ nhớ của mình, tôi thực sự cần kiểm soát chính xác và quét rác sẽ giết chết tôi. Do đó tôi đang thực hiện dự án này trong C ++. Nhưng sự lựa chọn đó dường như là một sự kiện vài năm một lần đối với tôi. (Hy vọng sau vài tuần nữa tôi sẽ không chạm vào C ++ thêm vài năm nữa.)


4
Thái độ này là cách chúng tôi kết thúc với phần mềm doanh nghiệp cồng kềnh trên các máy tính cực kỳ chậm mà cứ phân trang. Mọi người đều nói 'Chắc chắn ứng dụng của tôi chiếm nhiều bộ nhớ hơn, nhưng ai quan tâm, nó thực sự miễn phí!' và sau đó bạn kết thúc với một chồng đầy đủ các ứng dụng ngốn bộ nhớ khiến cho máy RAM 4GB chạy chậm hơn so với máy RAM 512 MB đã làm cách đây 10 năm.
MrFox

@MrFox Thực sự vấn đề với phần mềm doanh nghiệp là những người quyết định sử dụng nó không phải là những người phải chịu đựng nó. Xem danh sách.canonical.org/pipermail/kragen-tol/2005-April/000772.html để biết mô tả tuyệt vời về lý do tại sao nó bị hỏng. Đối với phần còn lại, bạn có bỏ lỡ việc tôi chỉ ra rằng việc lo lắng về việc sử dụng bộ nhớ đôi khi là cần thiết?
btilly

3

Đối với những người liên quan đến quản lý bộ nhớ "dữ liệu lớn" vẫn là một vấn đề lớn. Các chương trình về thiên văn học, vật lý, tin sinh học, học máy, v.v., tất cả đều phải xử lý các bộ dữ liệu nhiều gigabyte và các chương trình chạy nhanh hơn rất nhiều nếu các phần có liên quan có thể được giữ trong bộ nhớ. Ngay cả khi chạy trên máy có 128GB RAM cũng không giải quyết được vấn đề.

Ngoài ra còn có vấn đề tận dụng GPU, mặc dù có lẽ bạn sẽ phân loại đó là một hệ thống nhúng. Hầu hết những suy nghĩ khó khăn trong việc sử dụng CUDA hoặc OpenCL đều giải quyết vấn đề quản lý bộ nhớ trong việc chuyển dữ liệu từ bộ nhớ chính sang bộ nhớ GPU.


1

Công bằng mà nói, rất nhiều Java ngoài kia có một số kiểu nổ thực sự và vô nghĩa chỉ giết chết hiệu năng và bộ nhớ hog nhưng tôi tự hỏi bao nhiêu bộ nhớ đó chỉ là JVM mà theo lý thuyết (heh) hãy để bạn chạy cùng một ứng dụng trong nhiều môi trường mà không phải viết lại hoàn toàn những cái mới. Do đó, câu hỏi đánh đổi thiết kế tất cả tập trung vào: "Bao nhiêu bộ nhớ người dùng của bạn là một lợi thế phát triển đáng giá cho bạn?"

Đây là, IMO một sự đánh đổi hoàn toàn xứng đáng và hợp lý để xem xét. Điều làm tôi bực mình là khái niệm rằng vì các PC hiện đại rất mạnh và bộ nhớ quá rẻ, chúng tôi hoàn toàn có thể bỏ qua các mối quan tâm và các tính năng phình to như vậy và lười biếng về các lựa chọn đến mức có vẻ như rất nhiều thứ Bây giờ tôi làm trên PC Windows, chỉ mất như trong Window '95. Nghiêm túc mà nói, Word? Bao nhiêu crap mới mà 80% cơ sở người dùng của họ thực sự cần có thể có trong 18 năm qua? Khá chắc chắn rằng chúng tôi đã kiểm tra chính tả trước cửa sổ phải không? Nhưng chúng tôi đã nói về bộ nhớ không nhất thiết phải là tốc độ nếu bạn có nhiều bộ nhớ nên tôi lạc đề.

Nhưng tất nhiên, nếu bạn có thể hoàn thành ứng dụng trong 2 tuần với chi phí có thể thêm vài megabyte thay vì 2 năm để có phiên bản chỉ cần một vài K, thì đáng để xem xét một vài megs so sánh như thế nào ( Tôi đoán) 4-12 hợp đồng biểu diễn trên máy người dùng trung bình trước khi chế giễu ý tưởng quá cẩu thả.

Nhưng điều này có liên quan gì đến Scala ngoài câu hỏi đánh đổi? Chỉ vì đó là bộ sưu tập rác, không có nghĩa là bạn không nên luôn cố gắng suy nghĩ về luồng dữ liệu theo phạm vi và phạm vi đóng cửa và liệu nó có nên được đặt xung quanh hoặc sử dụng theo cách mà nó sẽ giải quyết bởi GC khi nó không còn cần thiết. Đó là điều mà ngay cả chúng tôi, các nhà phát triển web UI JavaScript đã phải suy nghĩ và hy vọng sẽ tiếp tục khi chúng tôi lan sang các lĩnh vực có vấn đề khác như ung thư hiểu biết hoàn hảo (rằng tất cả các bạn nên giết bằng Flash hoặc Applet hoặc thứ gì đó khi bạn có cơ hội) chúng tôi là thế.


0

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:

nhập mô tả hình ảnh ở đây

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ọ.

nhập mô tả hình ảnh ở đây

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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.