Tại sao bạn lập trình trong assembly? [đóng cửa]


86

Tôi có một câu hỏi cho tất cả các hacker cấp thấp khó tính ngoài kia. Tôi đã lướt qua câu này trong một blog. Tôi không thực sự nghĩ rằng nguồn quan trọng (đó là Haack nếu bạn thực sự quan tâm) bởi vì nó có vẻ là một tuyên bố phổ biến.

Ví dụ, nhiều Trò chơi 3-D hiện đại có công cụ lõi hiệu suất cao được viết bằng C ++ và Assembly.

Đối với hợp ngữ - là mã được viết trong hợp ngữ bởi vì bạn không muốn trình biên dịch phát ra các hướng dẫn bổ sung hoặc sử dụng quá nhiều byte hoặc bạn đang sử dụng các thuật toán tốt hơn mà bạn không thể diễn đạt bằng C (hoặc không thể diễn đạt mà không có trình biên dịch xem xét chúng)?

Tôi hoàn toàn hiểu rằng điều quan trọng là phải hiểu những thứ cấp thấp. Tôi chỉ muốn hiểu lý do tại sao chương trình trong hợp ngữ sau khi bạn hiểu nó.


1
Những câu hỏi tương tự đã có, tôi nghĩ là ...
Mehrdad Afshari

8
Eeeeehh .. về mặt kỹ thuật thì đây là một câu hỏi khác. Những câu hỏi đó là cả lý do tại sao học assembly, đây là lý do tại sao chương trình trong đó, mà .. Tôi nghĩ là khác ....?
cgp

4
Tại sao bạn lập trình trong assembly? - Hãy xem xét một số câu trả lời cho những câu hỏi IMPOSSIBLE rằng: 1) Để thực hiện duy trì mã của tôi, 2) linh hoạt, 3) để xảy tính di động, 4) testability, 5) khả năng đọc, ...;)
ivan_ivanovich_ivanoff

9
an ninh công việc ........
San Jacinto

3
bởi vì nó là niềm vui .. :)
RainedComputers

Câu trả lời:


169

Tôi nghĩ rằng bạn đang đọc sai tuyên bố này:

Ví dụ, nhiều Trò chơi 3-D hiện đại có công cụ lõi hiệu suất cao được viết bằng C ++ và Assembly.

Trò chơi (và hầu hết các chương trình ngày nay) không được "viết bằng assembly" giống như cách chúng được "viết bằng C ++". Blog đó không nói rằng một phần đáng kể trò chơi được thiết kế dưới dạng lắp ráp hay một nhóm lập trình viên ngồi xung quanh và phát triển bằng hợp ngữ làm ngôn ngữ chính của họ.

Điều này thực sự có nghĩa là các nhà phát triển đầu tiên viết trò chơi và làm cho nó hoạt động bằng C ++. Sau đó, họ lập hồ sơ, tìm ra những điểm nghẽn và nếu điều đó đáng giá, họ sẽ tối ưu hóa chúng trong quá trình lắp ráp. Hoặc, nếu họ đã có kinh nghiệm, họ biết phần nào sẽ là nút thắt cổ chai và họ có các phần được tối ưu hóa từ các trò chơi khác mà họ đã xây dựng.

Các điểm của lập trình trong lắp ráp cũng giống như nó luôn luôn là: tốc độ . Sẽ là vô lý nếu viết nhiều mã trong trình hợp dịch, nhưng có một số tối ưu hóa mà trình biên dịch không nhận thức được và đối với một cửa sổ mã đủ nhỏ, con người sẽ làm tốt hơn.

Ví dụ, đối với dấu phẩy động, các trình biên dịch có xu hướng khá thận trọng và có thể không nhận thức được một số tính năng nâng cao hơn trong kiến ​​trúc của bạn. Nếu bạn sẵn sàng chấp nhận một số lỗi, bạn thường có thể làm tốt hơn so với trình biên dịch, và bạn nên viết một đoạn mã nhỏ đó trong lắp ráp nếu bạn thấy rằng đã dành nhiều thời gian cho nó.

Dưới đây là một số ví dụ có liên quan hơn:

Ví dụ từ Trò chơi

  • Bài viết từ Intel về tối ưu hóa công cụ trò chơi bằng cách sử dụng bản chất SSE. Mã cuối cùng sử dụng bản chất (không phải trình hợp ngữ nội tuyến), vì vậy số lượng lắp ráp thuần túy là rất nhỏ. Nhưng họ xem xét đầu ra của trình hợp dịch bởi trình biên dịch để tìm ra chính xác những gì cần tối ưu hóa.

  • Căn bậc hai nghịch đảo nhanh của Quake . Một lần nữa, quy trình không có trình hợp ngữ trong đó, nhưng bạn cần biết một số điều về kiến ​​trúc để thực hiện loại tối ưu hóa này. Các tác giả biết hoạt động nào là nhanh (nhân, chuyển) và hoạt động nào là chậm (chia, sqrt). Vì vậy, họ đưa ra một cách triển khai căn bậc hai rất phức tạp để tránh hoàn toàn các hoạt động chậm chạp.

Máy tính hiệu suất cao

  • Bên ngoài lĩnh vực trò chơi, những người trong lĩnh vực máy tính khoa học thường tối ưu hóa mọi thứ để giúp chúng chạy nhanh trên phần cứng mới nhất. Hãy coi đây là trò chơi mà bạn không thể gian lận về vật lý.

    Một ví dụ tuyệt vời gần đây về điều này là Sắc động lực học lượng tử mạng (Lattice QCD) . Bài viết này mô tả cách thức vấn đề khá nhiều sôi xuống một kernel tính toán rất nhỏ, được tối ưu hóa nặng nề cho PowerPC 440 của trên một IBM Blue Gene / L . Mỗi 440 có hai FPU và chúng hỗ trợ một số hoạt động bậc ba đặc biệt mà trình biên dịch khó khai thác. Nếu không có những tối ưu hóa này, Lattice QCD sẽ chạy chậm hơn nhiều, điều này gây tốn kém khi vấn đề của bạn đòi hỏi hàng triệu giờ CPU trên các máy đắt tiền.

    Nếu bạn đang tự hỏi tại sao điều này lại quan trọng, hãy xem bài báo trên tạp chí Science về công trình này. Sử dụng Lattice QCD, những người này đã tính toán khối lượng của một proton từ các nguyên tắc đầu tiên, và cho thấy năm ngoái rằng 90% khối lượng đến từ năng lượng liên kết lực mạnh, và phần còn lại từ các hạt quark. Đó là E = mc 2 đang hoạt động. Đây là một bản tóm tắt .

Đối với tất cả những điều trên, các ứng dụng không được thiết kế hoặc viết 100% trong lắp ráp - thậm chí không đóng. Nhưng khi mọi người thực sự cần tốc độ, họ tập trung vào việc viết các phần chính của mã của họ để bay trên phần cứng cụ thể.


12
phản ứng đáng kinh ngạc. Ước gì chúng ta có thể đưa nó vào wiki!
bdd

6
@Paperino ... bạn có thể. Các câu hỏi và câu trả lời trên StackOverflow là phân bổ chung quảng cáo được cấp phép.
Aaron Maenpaa

Để biết thêm về cách hiểu asm để giúp bạn viết C / C ++ tốt hơn, hãy xem Tại sao mã C ++ này nhanh hơn so với lắp ráp viết tay của tôi để kiểm tra phỏng đoán Collatz? . Câu trả lời của tôi ở đó chỉ ra rằng đọc đầu ra asm của trình biên dịch và điều chỉnh nguồn có thể hữu ích khi trình biên dịch không nhận thấy một tối ưu hóa hữu ích. Vì vậy, bạn tinh thần (hay thực sự) ghi trong asm, sau đó tay giữ biên dịch để làm những gì bạn muốn, nhưng bây giờ bạn có C. di động tương lai chứng minh
Peter Cordes

42

Tôi đã không viết mã bằng hợp ngữ trong nhiều năm, nhưng tôi có thể đưa ra một số lý do mà tôi thường thấy:

  • Không phải tất cả các trình biên dịch đều có thể sử dụng các bộ lệnh và tối ưu hóa CPU nhất định (ví dụ: các bộ lệnh mới thỉnh thoảng được Intel thêm vào). Chờ đợi những người viết trình biên dịch bắt kịp đồng nghĩa với việc đánh mất lợi thế cạnh tranh.

  • Dễ dàng khớp mã thực tế hơn với kiến ​​trúc và tối ưu hóa CPU đã biết. Ví dụ, những điều bạn biết về cơ chế tìm nạp, bộ nhớ đệm,… Điều này được cho là minh bạch với nhà phát triển, nhưng thực tế là không phải vậy, đó là lý do tại sao người viết trình biên dịch có thể tối ưu hóa.

  • Các truy cập cấp phần cứng nhất định chỉ có thể / thực tế thông qua hợp ngữ (ví dụ: khi viết trình điều khiển thiết bị).

  • Lập luận chính thức đôi khi thực sự dễ dàng hơn đối với hợp ngữ hơn là đối với ngôn ngữ cấp cao vì bạn đã biết bố cục cuối cùng hoặc gần như cuối cùng của mã là gì.

  • Lập trình một số thẻ đồ họa 3D nhất định (khoảng cuối những năm 1990) khi không có API thường thực tế và hiệu quả hơn bằng ngôn ngữ hợp ngữ, và đôi khi không thể thực hiện được bằng các ngôn ngữ khác. Nhưng một lần nữa, điều này liên quan đến các trò chơi thực sự cấp chuyên gia dựa trên kiến ​​trúc bộ tăng tốc như di chuyển dữ liệu vào và ra theo cách thủ công theo thứ tự nhất định.

Tôi nghi ngờ nhiều người sử dụng hợp ngữ khi một ngôn ngữ cấp cao hơn sẽ làm được điều đó, đặc biệt là khi ngôn ngữ đó là C. Tối ưu hóa bằng tay một lượng lớn mã mục đích chung là không thực tế.


19

Có một khía cạnh của lập trình trình hợp dịch mà những người khác chưa đề cập đến - cảm giác hài lòng mà bạn nhận được khi biết rằng mỗi byte đơn lẻ trong một ứng dụng là kết quả của nỗ lực của chính bạn, không phải của trình biên dịch. Tôi sẽ không một giây nào muốn quay lại viết toàn bộ ứng dụng trong trình lắp ráp như tôi đã từng làm vào đầu những năm 80, nhưng đôi khi tôi nhớ cảm giác đó ...


3
Heh, đó là kết quả của công việc của người lắp ráp! Bạn thường viết nhiều macro trong asm.
Mehrdad Afshari

5
Không chỉ là sự hài lòng mà còn là sự đánh giá cao về độ chính xác. Một quá trình ngắn gọn với tất cả mọi thứ về nó được tuyên bố là một niềm vui được nhìn thấy.
deau

18

Thông thường, lắp ráp của giáo dân chậm hơn C (do sự tối ưu hóa của C) nhưng nhiều trò chơi (tôi nhớ rõ là Doom ) phải có các phần cụ thể của trò chơi trong Assembly để nó chạy trơn tru trên các máy bình thường.

Đây là ví dụ mà tôi đang đề cập đến.


2
+1 Rất đúng. Con người rất tệ trong việc viết mã asm dài.
Tài khoản chết

Hãy nhớ rằng các công cụ đã nói không phải lúc nào cũng có sẵn khi trình lắp ráp được viết.
Marco van de Voort

16

Tôi bắt đầu lập trình chuyên nghiệp bằng hợp ngữ trong công việc đầu tiên của mình (những năm 80). Đối với các hệ thống nhúng, nhu cầu bộ nhớ - RAM và EPROM - rất thấp. Bạn có thể viết mã chặt chẽ dễ dàng trên tài nguyên.

Vào cuối những năm 80, tôi đã chuyển sang C. Mã dễ viết, gỡ lỗi và bảo trì hơn. Những đoạn mã rất nhỏ được viết bằng trình hợp dịch - đối với tôi, đó là khi tôi đang viết chuyển đổi ngữ cảnh trong RTOS của riêng bạn. (Điều gì đó bạn không nên làm nữa trừ khi nó là một "dự án khoa học".)

Bạn sẽ thấy các đoạn mã trình hợp dịch trong một số mã nhân Linux. Gần đây nhất, tôi đã duyệt qua nó trong spinlock và mã đồng bộ hóa khác. Những đoạn mã này cần có quyền truy cập vào các hoạt động thử nghiệm và thiết lập nguyên tử, thao tác bộ nhớ đệm, v.v.

Tôi nghĩ rằng bạn sẽ khó tối ưu hóa các trình biên dịch C hiện đại cho hầu hết các chương trình chung.

Tôi đồng ý với @altCognito rằng thời gian của bạn có lẽ nên dành để suy nghĩ kỹ hơn về vấn đề và làm mọi thứ tốt hơn. Vì một số lý do, các lập trình viên thường tập trung vào hiệu quả vi mô và bỏ qua hiệu quả vĩ mô. Hợp ngữ để cải thiện hiệu suất là một hiệu quả vi mô. Lùi lại để có cái nhìn rộng hơn về hệ thống có thể phơi bày các vấn đề vĩ mô trong một hệ thống. Giải quyết các vấn đề vĩ mô thường có thể mang lại hiệu suất tốt hơn. Một khi các vấn đề vĩ mô được giải quyết thì sẽ thu gọn về cấp vi mô.

Tôi đoán các vấn đề vi mô nằm trong tầm kiểm soát của một lập trình viên duy nhất và trong một miền nhỏ hơn. Thay đổi hành vi ở cấp độ vĩ mô đòi hỏi giao tiếp với nhiều người hơn - một điều mà một số lập trình viên tránh. Đó là toàn bộ cao bồi và điều đồng đội.


10

"Đúng". Tuy nhiên, hãy hiểu rằng phần lớn lợi ích của việc viết mã trong trình hợp dịch không đáng để bạn nỗ lực. Lợi nhuận nhận được khi viết nó trong tập hợp có xu hướng nhỏ hơn so với việc chỉ tập trung vào việc suy nghĩ kỹ hơn về vấn đề và dành thời gian của bạn để nghĩ ra cách tốt hơn để thực hiện.

John Carmack và Michael Abrash, những người chịu trách nhiệm chính trong việc viết Quake và tất cả mã hiệu suất cao được sử dụng trong các công cụ chơi game ID sẽ đi sâu vào vấn đề này trong cuốn sách này .

Tôi cũng đồng ý với Ólafur Waage rằng ngày nay, các trình biên dịch khá thông minh và thường sử dụng nhiều kỹ thuật tận dụng các tính năng tăng cường kiến ​​trúc ẩn.


9

Ngày nay, đối với các mã tuần tự, ít nhất là một trình biên dịch tốt hầu như luôn đánh bại ngay cả một lập trình viên hợp ngữ dày dạn kinh nghiệm. Nhưng đối với mã vector thì lại là một câu chuyện khác. Ví dụ, các trình biên dịch được triển khai rộng rãi không làm được công việc tuyệt vời như vậy khi khai thác các khả năng vector-song song của đơn vị x86 SSE. Tôi là một người viết trình biên dịch và việc khai thác SSE đứng đầu danh sách các lý do của tôi để bạn tự thực hiện thay vì tin tưởng trình biên dịch.


Trong trường hợp đó, tôi sẽ sử dụng một trình biên dịch nội tại.
Mehrdad Afshari

Vẫn không giống nhau. Nó giống như một trình biên dịch mà không cần đăng ký ưu
Marco van de Voort

Nó phụ thuộc vào loại gia vị mà lập trình viên asm của bạn có. Nếu bạn đã đọc và tìm kiếm agner.org/optimize để tìm hiểu về vi kiến ​​trúc mà bạn đang điều chỉnh, việc đánh bại trình biên dịch chỉ cho các chuỗi ngắn thường rất dễ dàng . Ít nhất một nửa thời gian tôi thấy các tối ưu hóa nhỏ bị bỏ lỡ khi xem đầu ra của trình biên dịch cho các chức năng nhỏ. Nơi mà các trình biên dịch tuyệt vời là việc tối ưu hóa trên các cơ sở mã lớn với sự lan truyền nội tuyến và liên tục.
Peter Cordes

8

Mã SSE hoạt động tốt hơn trong lắp ráp so với bản chất của trình biên dịch, ít nhất là trong MSVC. (tức là không tạo thêm các bản sao dữ liệu)


Điểm tốt, bạn cần một trình biên dịch hoạt động tốt với bản chất. Các trình biên dịch Intel và Gnu khá tốt, tôi không biết liệu bản mới nhất từ ​​PGI và PathScale có cạnh tranh được hay không, trước đây chúng đã từng như vậy.
Jed

6

Tôi đã có ba hoặc bốn quy trình trình hợp dịch (trong nguồn khoảng 20 MB) trong các nguồn của tôi tại nơi làm việc. Tất cả chúng đều là SSE (2) và liên quan đến các hoạt động trên hình ảnh (khá lớn - hãy nghĩ đến 2400x2048 và lớn hơn).

Vì sở thích, tôi làm việc trên một trình biên dịch, và ở đó bạn có nhiều trình biên dịch hơn. Thư viện thời gian chạy thường khá đầy chúng, hầu hết chúng liên quan đến những thứ bất chấp chế độ thủ tục thông thường (như trình trợ giúp cho các trường hợp ngoại lệ, v.v.)

Tôi không có bất kỳ trình lắp ráp nào cho bộ vi điều khiển của mình. Hầu hết các bộ vi điều khiển hiện đại đều có rất nhiều phần cứng ngoại vi (bộ đếm điều khiển ngắt, thậm chí toàn bộ bộ mã hóa cầu phương và các khối xây dựng nối tiếp) nên việc sử dụng trình hợp dịch để tối ưu hóa các vòng lặp thường không còn cần thiết nữa. Với giá flash hiện tại, bộ nhớ mã cũng vậy. Ngoài ra, thường có nhiều thiết bị tương thích với pin, vì vậy nâng cấp nếu bạn sử dụng hết nguồn cpu hoặc dung lượng flash một cách có hệ thống thường không phải là vấn đề

Trừ khi bạn thực sự xuất xưởng 100000 thiết bị và trình lắp ráp lập trình giúp bạn có thể thực sự tiết kiệm đáng kể bằng cách lắp vào chip flash một loại nhỏ hơn. Nhưng tôi không thuộc loại đó.

Nhiều người nghĩ rằng nhúng là một cái cớ cho trình lắp ráp, nhưng bộ điều khiển của họ có nhiều sức mạnh CPU hơn so với máy Unix được phát triển trên đó. (Vi mạch đi kèm với vi điều khiển MIPS 40 và 60 với giá dưới 10 USD ).

Tuy nhiên, rất nhiều người bị mắc kẹt với di sản, vì việc thay đổi kiến ​​trúc vi mạch không hề dễ dàng. Ngoài ra, mã HLL rất phụ thuộc vào kiến ​​trúc (vì nó sử dụng ngoại vi phần cứng, các thanh ghi để điều khiển I / O, v.v.). Vì vậy, đôi khi có những lý do chính đáng để tiếp tục duy trì một dự án trong trình lắp ráp (tôi thật may mắn khi có thể thiết lập các công việc trên một kiến ​​trúc mới từ đầu). Nhưng thường mọi người tự đùa rằng họ thực sự cần người lắp ráp.

Tôi vẫn thích câu trả lời của một giáo sư khi chúng tôi hỏi liệu chúng tôi có thể sử dụng GOTO hay không (nhưng bạn cũng có thể đọc là ASSEMBLER): "nếu bạn nghĩ rằng đáng để viết một bài luận dài 3 trang về lý do tại sao bạn cần tính năng này, bạn có thể sử dụng nó. . Hãy gửi bài luận cùng với kết quả của bạn. "

Tôi đã sử dụng nó như một nguyên tắc hướng dẫn cho các tính năng cấp thấp. Đừng quá chật chội để sử dụng nó, nhưng hãy đảm bảo rằng bạn thúc đẩy nó đúng cách. Thậm chí, hãy dựng lên một hoặc hai rào cản nhân tạo (như bài luận) để tránh lập luận phức tạp như biện minh.


1
Tôi thích bài kiểm tra luận; Tôi có thể cần phải sử dụng này thường xuyên hơn;)
cựu nihilo

5

Một số hướng dẫn / cờ / điều khiển đơn giản là không có ở cấp C.

Ví dụ: kiểm tra tràn trên x86 là cờ tràn đơn giản. Tùy chọn này không khả dụng trong C.


Bạn có thể tính toán các cờ tràn trong C bằng các phép toán bit.
swegi 07-07-09

@swegi: Tôi cá là chậm hơn không đáng kể.
Brian

mức độ thường xuyên là hữu ích? và khi đúng như vậy, nó không thể là lý do duy nhất để bạn rơi vào trình lắp ráp.

5

Các khiếm khuyết có xu hướng chạy trên mỗi dòng (câu lệnh, điểm mã, v.v.); mặc dù sự thật là đối với hầu hết các vấn đề, hợp ngữ sẽ sử dụng nhiều dòng hơn nhiều so với các ngôn ngữ cấp cao hơn, đôi khi có những trường hợp mà cách tốt nhất (ngắn gọn nhất, ít dòng nhất) ánh xạ đến vấn đề đang xảy ra. Hầu hết các trường hợp này liên quan đến các nghi phạm thông thường, chẳng hạn như trình điều khiển và bit-banging trong các hệ thống nhúng.


3

Một lý do khác có thể là khi trình biên dịch có sẵn không đủ tốt cho một kiến ​​trúc và số lượng mã cần thiết trong chương trình không dài hoặc phức tạp để lập trình viên bị lạc vào đó. Hãy thử lập trình vi điều khiển cho một hệ thống nhúng, thông thường việc lắp ráp sẽ dễ dàng hơn nhiều.


3

Bên cạnh những điều đã đề cập khác, tất cả các ngôn ngữ cao hơn đều có những hạn chế nhất định. Đó là lý do tại sao một số người chọn lập trình trong ASM, để có toàn quyền kiểm soát mã của họ.

Những người khác thích các tệp thực thi rất nhỏ, trong khoảng 20-60KB, ví dụ kiểm tra HiEditor , được thực hiện bởi tác giả của điều khiển HiEdit, kiểm soát chỉnh sửa tuyệt vời cho Windows với đánh dấu cú pháp và các tab chỉ trong ~ 50kb). Trong bộ sưu tập của mình, tôi có hơn 20 điều khiển vàng như vậy từ Excell như ssheets đến kết xuất html.


3

Tôi nghĩ rằng rất nhiều nhà phát triển trò chơi sẽ ngạc nhiên về thông tin này.

Hầu hết các trò chơi tôi biết sử dụng càng ít lắp ráp càng tốt. Trong một số trường hợp, không có gì cả, và tệ nhất là một hoặc hai vòng lặp hoặc hàm.

Câu nói đó được khái quát quá mức và không đúng như cách đây một thập kỷ.

Nhưng này, sự thật đơn thuần không nên cản trở cuộc thập tự chinh của một hacker thực sự ủng hộ việc lắp ráp. ;)


3

Nếu bạn đang lập trình một bộ vi điều khiển 8 bit cấp thấp với 128 byte RAM và 4K bộ nhớ chương trình, bạn không có nhiều lựa chọn về việc sử dụng lắp ráp. Đôi khi, khi sử dụng bộ vi điều khiển mạnh hơn, bạn cần một hành động nhất định diễn ra vào một thời điểm chính xác. Khi đó ngôn ngữ hợp ngữ trở nên hữu ích vì bạn có thể đếm các lệnh và do đó, đo các chu kỳ đồng hồ được sử dụng bởi mã của bạn.


2

Nếu bạn luôn nỗ lực sửa chữa Y2K, bạn có thể kiếm được rất nhiều tiền nếu bạn biết Assembly. Vẫn còn rất nhiều mã kế thừa xung quanh được viết trong đó và mã đó đôi khi cần được bảo trì.


2

Ngoài các dự án rất nhỏ trên các CPU rất nhỏ, tôi sẽ không bắt đầu lập trình toàn bộ một dự án trong lắp ráp. Tuy nhiên, người ta thường thấy rằng nút cổ chai về hiệu suất có thể được giải tỏa bằng cách viết tay chiến lược của một số vòng lặp bên trong.

Trong một số trường hợp, tất cả những gì thực sự cần thiết là thay thế một số cấu trúc ngôn ngữ bằng một chỉ dẫn mà trình tối ưu hóa không thể tìm ra cách sử dụng. Một ví dụ điển hình là trong các ứng dụng DSP, nơi mà các phép toán vectơ và phép toán nhân-tích lũy rất khó để trình tối ưu hóa phát hiện ra, nhưng lại dễ sử dụng mã.

Ví dụ, một số mô hình nhất định của SH4 chứa ma trận 4x4 và 4 lệnh vectơ. Tôi đã thấy sự cải thiện hiệu suất rất lớn trong thuật toán hiệu chỉnh màu bằng cách thay thế các thao tác C tương đương trên ma trận 3x3 bằng các lệnh thích hợp, với chi phí rất nhỏ là phóng to ma trận hiệu chỉnh lên 4x4 để phù hợp với giả định phần cứng. Điều đó đạt được bằng cách viết không quá một chục dòng lắp ráp và thực hiện các điều chỉnh phù hợp với các kiểu dữ liệu liên quan và lưu trữ vào một số ít các vị trí trong mã C xung quanh.


2

Nó dường như không được đề cập đến, vì vậy tôi nghĩ tôi sẽ thêm nó vào: trong phát triển trò chơi hiện đại, tôi nghĩ rằng ít nhất một số lắp ráp được viết không dành cho CPU. Nó dành cho GPU, dưới dạng các chương trình đổ bóng .

Điều này có thể cần thiết vì đủ loại lý do, đôi khi chỉ đơn giản là vì bất kỳ ngôn ngữ tô bóng cấp cao hơn nào được sử dụng không cho phép thể hiện chính xác hoạt động theo số lượng lệnh chính xác mà bạn muốn, để phù hợp với một số ràng buộc về kích thước, tốc độ hoặc bất kỳ sự kết hợp nào . Tôi đoán cũng như thường lệ với lập trình hợp ngữ.


2

Hầu hết mọi công cụ hoặc thư viện trò chơi từ trung bình đến lớn mà tôi đã thấy cho đến nay đều có một số phiên bản lắp ráp được tối ưu hóa bằng tay có sẵn cho các hoạt động ma trận như nối ma trận 4x4. Có vẻ như các trình biên dịch chắc chắn bỏ lỡ một số tối ưu hóa thông minh (sử dụng lại thanh ghi, hủy cuộn vòng một cách hiệu quả tối đa, tận dụng các hướng dẫn dành riêng cho máy, v.v.) khi làm việc với ma trận lớn. Các chức năng thao tác ma trận này hầu như luôn luôn là "điểm nóng" trên hồ sơ.

Tôi cũng đã thấy lắp ráp mã hóa thủ công được sử dụng rất nhiều cho việc gửi tùy chỉnh - những thứ như FastDelegate, nhưng trình biên dịch và máy cụ thể.

Cuối cùng, nếu bạn có Quy trình dịch vụ ngắt, asm có thể tạo ra tất cả sự khác biệt trên thế giới - có một số hoạt động nhất định bạn không muốn xảy ra khi bị ngắt và bạn muốn trình xử lý ngắt của mình "vào và ra nhanh". .. bạn biết gần như chính xác điều gì sẽ xảy ra trong ISR của mình nếu nó ở trong asm, và nó khuyến khích bạn giữ những nội dung ngắn gọn (dù sao cũng là cách làm tốt).


2

Trò chơi có hiệu suất khá cao và mặc dù trong khi đó, các trình tối ưu hóa khá tốt, một "lập trình viên bậc thầy" vẫn có thể tăng hiệu suất bằng cách viết tay các bộ phận phù hợp trong lắp ráp.

Đừng bao giờ bắt đầu tối ưu hóa chương trình của bạn mà không lập hồ sơ trước. Sau khi lập hồ sơ sẽ có thể xác định các nút thắt cổ chai và nếu việc tìm thấy các thuật toán tốt hơn và những thứ tương tự không cắt được nữa, bạn có thể thử viết tay một số thứ trong lắp ráp.


2

Cá nhân tôi chỉ nói chuyện với một nhà phát triển về việc sử dụng lắp ráp. Anh ấy đang làm việc trên phần sụn xử lý các điều khiển cho một máy nghe nhạc mp3 di động. Thực hiện công việc lắp ráp có 2 mục đích:

  1. Tốc độ: độ trễ cần thiết ở mức tối thiểu.
  2. Chi phí: bằng cách tối thiểu với mã, phần cứng cần thiết để chạy nó có thể kém mạnh hơn một chút. Khi sản xuất hàng loạt hàng triệu đơn vị, điều này có thể tăng lên.

2

Mã hóa trình hợp dịch duy nhất mà tôi tiếp tục làm là cho phần cứng nhúng với tài nguyên ít ỏi. Như Leander đã đề cập, lắp ráp vẫn rất phù hợp với ISR nơi mã cần phải nhanh và được hiểu rõ.

Một lý do phụ đối với tôi là giữ kiến ​​thức của tôi về chức năng lắp ráp. Có thể kiểm tra và hiểu các bước mà CPU đang thực hiện để thực hiện việc đặt giá thầu của tôi thật tuyệt.


2

Lần cuối cùng tôi viết trong trình hợp dịch là khi tôi không thể thuyết phục trình biên dịch tạo mã độc lập, không có libc.

Lần sau có lẽ sẽ vì lý do tương tự.

Tất nhiên, tôi từng có những lý do khác .


2

Rất nhiều người thích phỉ báng hợp ngữ bởi vì họ chưa bao giờ học cách viết mã với nó và chỉ mơ hồ gặp nó và nó khiến họ kinh ngạc hoặc có phần sợ hãi. Các lập trình viên tài năng thực sự sẽ hiểu rằng việc đánh giá C hoặc Assembly là vô nghĩa vì chúng bổ sung cho nhau. trong thực tế, lợi thế của một trong những bất lợi của kia. Các quy tắc cú pháp có tổ chức của C cải thiện sự rõ ràng nhưng đồng thời loại bỏ tất cả các tập hợp quyền lực có được khỏi bất kỳ quy tắc cấu trúc nào! Hướng dẫn mã C được thực hiện để tạo mã không chặn, điều này có thể được lập luận buộc sự rõ ràng của ý định lập trình nhưng đây là một tổn thất điện năng. Trong C, trình biên dịch sẽ không cho phép nhảy bên trong if / elseif / else / end. Hoặc bạn không được phép viết hai vòng lặp for / end trên các biến khác nhau chồng chéo lên nhau, bạn không thể viết mã tự sửa đổi (hoặc không thể theo cách dễ dàng liền mạch), v.v. các lập trình viên thông thường bị những điều trên làm cho kinh ngạc và thậm chí sẽ không biết cách sử dụng sức mạnh của các phương pháp này vì chúng đã được nâng lên để tuân theo các quy tắc thông thường . Đây là sự thật: Ngày nay chúng ta có máy móc với sức mạnh tính toán để làm được nhiều việc hơn ứng dụng mà chúng ta sử dụng chúng nhưng bộ não con người không có khả năng mã hóa chúng trong một môi trường mã hóa không có quy tắc (= assembly) và cần các quy tắc hạn chế giảm phổ và đơn giản hóa mã hóa. Bản thân tôi đã viết mã không thể viết bằng mã C mà không trở nên cực kỳ kém hiệu quả vì những hạn chế đã đề cập ở trên. Và tôi vẫn chưa nói về tốc độ mà hầu hết mọi người nghĩ là lý do chính để ghi trong lắp ráp, tốt là nếu tâm trí bạn bị giới hạn trong việc suy nghĩ trong C thì bạn là nô lệ của trình biên dịch của bạn mãi mãi. Tôi luôn nghĩ những bậc thầy chơi cờ sẽ là những lập trình viên lắp ráp lý tưởng trong khi những người lập trình C chỉ chơi "Dames".


1
mã tự sửa đổi không hữu ích cho hiệu suất trên hầu hết các CPU hiện đại, ngoài các kịch bản JIT-một lần / chạy-nhiều. Nhưng điền vào các hằng số ngay lập tức là một khả năng thú vị. Tuy nhiên, C gotocho phép các bước nhảy không có cấu trúc trong một hàm. Bao gồm vào một khối bên trong một if()hoặc vòng lặp trong cùng một chức năng. ví dụ: godbolt.org/z/IINHTg . Xem thêm Thiết bị của Duff, sử dụng công tắc / trường hợp vào một do{}while()vòng lặp để thể hiện bước nhảy vào một vòng lặp chưa cuộn. Nhưng đến một lúc nào đó, việc viết bằng asm có thể trở nên rõ ràng hơn nếu bạn đang rơi vào mức độ lộn xộn đó.
Peter Cordes

1
(Tất nhiên, thiết bị Duff là chỉ hữu ích trên máy với thời hậu increment giải quyết, nếu không những điểm vào bên trong vòng lặp unrolled chỉ đánh bại hầu hết các mục đích của việc tối ưu hóa.)
Peter Cordes

1

Không còn là tốc độ, mà là Kiểm soát . Tốc độ đôi khi sẽ đến từ sự kiểm soát, nhưng nó là lý do duy nhất để viết mã trong lắp ráp. Mọi lý do khác đều nằm trong tầm kiểm soát (tức là SSE và tối ưu hóa mặt khác, trình điều khiển thiết bị và mã phụ thuộc thiết bị, v.v.).


1

Nếu tôi có thể làm tốt hơn GCC và Visual C ++ 2008 (còn được gọi là Visual C ++ 9.0) thì mọi người sẽ quan tâm đến việc phỏng vấn tôi về khả năng đó.

Đây là lý do tại sao hiện tại tôi chỉ đọc mọi thứ trong assembly và chỉ viết __asm ​​int 3 khi được yêu cầu.

Tôi hy vọng điều này sẽ giúp ...


1

Tôi đã không viết trong assembly trong một vài năm, nhưng hai lý do tôi từng làm là:

  • Thách thức của điều này! Tôi đã trải qua khoảng thời gian vài tháng cách đây nhiều năm khi tôi viết mọi thứ trong x86 assembly (thời của DOS và Windows 3.1). Về cơ bản, nó đã dạy tôi một số thao tác cấp thấp, I / O phần cứng , v.v.
  • Đối với một số thứ, nó giữ kích thước nhỏ (một lần nữa DOS và Windows 3.1 khi viết TSR s)

Tôi tiếp tục xem xét việc lắp ráp mã hóa một lần nữa, và đó không gì khác hơn là thử thách và niềm vui. Tôi không có lý do nào khác để làm như vậy :-)


1

Tôi đã từng tiếp quản một dự án DSP mà lập trình viên trước đó đã viết hầu hết bằng mã hợp ngữ, ngoại trừ logic phát hiện giai điệu đã được viết bằng C, sử dụng dấu phẩy động (trên DSP điểm cố định!). Logic phát hiện giai điệu chạy ở khoảng 1/20 thời gian thực.

Tôi đã viết lại hầu hết mọi thứ từ đầu. Hầu hết mọi thứ đều ở dạng C ngoại trừ một số trình xử lý ngắt nhỏ và vài chục dòng mã liên quan đến xử lý ngắt và phát hiện tần số mức thấp, chạy nhanh hơn 100 lần so với mã cũ.

Một điều quan trọng cần ghi nhớ, tôi nghĩ, là trong nhiều trường hợp, sẽ có nhiều cơ hội lớn hơn để nâng cao tốc độ với các quy trình nhỏ hơn quy trình lớn, đặc biệt nếu trình hợp dịch viết tay có thể phù hợp với mọi thứ trong sổ đăng ký nhưng trình biên dịch thì không. khá quản lý. Nếu một vòng lặp đủ lớn mà nó không thể giữ mọi thứ trong sổ đăng ký, thì sẽ có ít cơ hội để cải thiện hơn.


0

Dalvik VM thông dịch mã bytecode cho các ứng dụng Java trên điện thoại Android sử dụng trình hợp dịch cho trình điều phối. Phim này (dài khoảng 31 phút, nhưng đáng xem cả bộ phim!) Giải thích cách

"vẫn có những trường hợp con người có thể làm tốt hơn trình biên dịch".


0

Tôi không, nhưng tôi đã nói rằng ít nhất tôi phải thử, và cố gắng hết sức vào một thời điểm nào đó trong quá trình phát triển (hy vọng sẽ sớm xảy ra). Không phải là một điều tồi tệ khi biết thêm về những thứ cấp thấp và cách mọi thứ hoạt động đằng sau hậu trường khi tôi lập trình bằng một ngôn ngữ cấp cao. Thật không may, rất khó để có một công việc toàn thời gian với tư cách là nhà phát triển / nhà tư vấn và cha mẹ. Nhưng tôi sẽ đưa ra đúng lúc, đó là điều chắc chắn.

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.