Khi được sử dụng như ngăn xếp cuộc gọi, các ngăn xếp spaghetti không rác tạo thành một DAG?


9

Tôi đang xem xét các kỹ thuật triển khai cho các ngôn ngữ lập trình, và gần đây đã bắt gặp các ngăn xếp spaghetti, được cho là phù hợp với mô hình kiểu truyền tiếp tục (được sử dụng trong ví dụ Scheme và SML / NJ ). Để đơn giản, chúng ta chỉ xem xét một quy trình đơn luồng cho câu hỏi này.

Tuy nhiên, tôi hơi bối rối bởi sơ đồ trên Wikipedia (cũng được tìm thấy ở nơi khác ). Cụ thể, tôi không hiểu làm thế nào một tình huống như vậy có thể phát sinh. Tôi chỉ có thể tưởng tượng rằng các nhánh màu xám là không thể truy cập và nên được thu gom rác. Mặt khác, với sự hiểu biết mơ hồ của tôi về cách triển khai CPS bằng cách sử dụng ngăn xếp spaghetti, tôi không thể tưởng tượng làm thế nào bạn có thể có được một vòng lặp trong cấu trúc đó. Tôi phải kết luận rằng, thay vì "cây con trỏ cha mẹ", nó thực sự là một biểu đồ chu kỳ có hướng, với càng nhiều nguồn không rác như có các luồng và càng nhiều điểm chìm càng có "điểm thoát" tiềm năng.

Nhưng sự hiểu biết của tôi về việc thực hiện này là khá mơ hồ, vì vậy tôi đoán có lẽ tôi đang thiếu một cái gì đó. Tôi hy vọng ai đó có thể khai sáng cho tôi ở đây về "ngăn xếp cuộc gọi spaghetti", ý tôi là cấu trúc dữ liệu như được sử dụng trong Đề án và / hoặc SML / NJ để thực hiện các quy trình dựa trên CPS.

  1. Cho ngăn xếp cuộc gọi spaghetti sau đây:

    [exit point] <-- ... <-- [frame A] <-- [frame B (active)]
                                    ^
                                     `---- [frame C]
    

    Theo như tôi hiểu, bất kỳ điều khiển luồng nào từ B đều sẽ ngăn xếp ngăn xếp bằng cách nhảy tới cha mẹ (A trở thành hoạt động, B không thể truy cập bây giờ là rác) hoặc thay thế khung hoạt động bằng một sơ đồ con, chỉ được kết nối bằng cách sử dụng các tham chiếu được giữ bởi B hoặc tham chiếu đến các khung mới. Việc thực thi không thể chảy vào khung C, điều đó có nghĩa là khung C là rác.

  2. Thay vì tình huống trước đó, tôi nghĩ rằng tình huống không có rác sau đây có thể phát sinh:

    [exit point] <-- ... <-- [frame W] <-- [frame X] <-- [frame Z (active)]
                                    ^                     |
                                     `---- [frame Y] <---´
    

    Ví dụ, tôi có thể tưởng tượng rằng khung Z thuộc về một số chức năng quyết định, tiếp tục với khung X hoặc khung Y (một trong hai khung này sẽ trở về W). Điều này có nghĩa là ngăn xếp cuộc gọi spaghetti không phải là " cây con trỏ cha mẹ ".

  3. Tuy nhiên, tôi không thể tưởng tượng bất kỳ tình huống nào mà một vòng lặp có thể được xây dựng. Lấy tình huống sau đây, ví dụ:

    [exit point] <-- ... <-- [frame P] --> [frame Q (active)]
                                    ^             |
                                    |             v
                                     `---- [frame R]
    

    Tôi biết rằng các ràng buộc đệ quy là một điều, nhưng tôi rất nghi ngờ rằng điều này là hợp lý. Nếu Q trở về R, khung Q là "chi". Nếu R trở về P và P không thể đơn giản quay lại Q, vì trước tiên nó cần phải được xác định lại. Như vậy, các vòng lặp sẽ gây ra các trạng thái không nhất quán. (Tất nhiên trừ khi tôi hiểu sai mục đích của cấu trúc dữ liệu này và bạn chỉ sử dụng các nút trong đó làm mẫu cho khung hiện tại của mình.)

Từ những quan sát này, tôi phải kết luận rằng một ngăn xếp cuộc gọi spaghetti (không có rác) thực sự là một DAG. Điều này có đúng không? Hay tôi đang hiểu sai mục đích của cấu trúc dữ liệu này?


Cập nhật:

  • Tôi đã đọc lướt qua một bản sao của bài báo sau:

    EA Hauck và BA Nha. Năm 1968. Cơ chế xếp chồng B6500 / B7500 của Burroughs. Trong Kỷ yếu 30 tháng 4 - 2 tháng 5 năm 1968, hội nghị máy tính chung mùa xuân (AFIPS '68 (Mùa xuân)). ACM, New York, NY, Hoa Kỳ, 245-251. DOI = http://dx.doi.org/10.1145/1468075.1468111

    Bài viết này dường như định nghĩa Hệ thống ngăn xếp Suguaro. Hóa ra, Hệ thống ngăn xếp Suguaro này là một ngăn xếp cuộc gọi truyền thống cho phép nhiều "công việc" đi qua các khung của ngăn xếp được chia sẻ một phần; nó hoàn toàn không liên quan đến sự tiếp nối

  • Bài báo sau (và bài báo đồng hành năm 1996) rõ ràng giải thích những gì đang diễn ra trong trình biên dịch SML / NJ:

    Zhong Shao và Andrew W. Appel. 2000. Chuyển đổi đóng cửa hiệu quả và an toàn cho không gian. ACM Trans. Chương trình. Lang. Hệ thống. 22, 1 (tháng 1 năm 2000), 129-161. DOI = http://dx.doi.org/10.1145 4325099.345125

    Tôi nghĩ rằng tôi nên đọc bài viết này ( sao chép trên trang web của tác giả ) trước khi làm bất cứ điều gì khác với câu hỏi này. Khái niệm "Đóng cửa liên kết an toàn" rất giống với Hệ thống ngăn xếp Suguaro, ở chỗ nó luôn rất nông và chỉ có ý định chia sẻ các biến miễn phí:

    Thuật toán chuyển đổi đóng cửa mới của chúng tôi sử dụng các bao đóng được liên kết an toàn (cột thứ 3 trong Hình 1) chỉ chứa các biến thực sự cần thiết trong hàm nhưng tránh sao chép đóng bằng cách nhóm các biến có cùng thời gian vào một bản ghi có thể chia sẻ. [...] Không giống như các lần đóng được liên kết, mức đóng của các lần đóng được liên kết an toàn không bao giờ vượt quá hai (một lớp cho chính lần đóng; lớp khác cho các bản ghi có thời gian sống khác nhau) vì vậy chúng vẫn có thời gian truy cập biến rất nhanh.

    Bài viết cũng đề cập rõ ràng rằng nó không sử dụng "bất kỳ ngăn xếp thời gian chạy" nào:

    Thay vào đó, chúng tôi coi tất cả các bản ghi kích hoạt là các bao đóng cho các hàm tiếp tục và phân bổ chúng trong các thanh ghi trên heap.

    Tôi nghĩ rằng tôi đã hiểu nhầm và / hoặc đọc sai bài viết Wikipedia, vì ngăn xếp spaghetti không được sử dụng để kiểm soát dòng chảy. Tuy nhiên, sau khi đọc kỹ các bài báo của Appel và Shao, có lẽ tôi có thể đặt lại câu hỏi liên quan đến biểu đồ phụ thuộc của các lần đóng thay vì "ngăn xếp cuộc gọi spaghetti" (dường như không phải là một vấn đề).


Hoàn thành tốt việc suy nghĩ cho bản thân và đặt câu hỏi về những khẳng định trong những gì bạn đọc. Tôi hy vọng bạn nhận được một câu trả lời tốt, nhưng tôi nghi ngờ bạn sẽ làm tốt mà không cần. :) (Và đừng quên trả lời câu hỏi của chính bạn nếu bạn có thể làm như vậy trong tương lai!)
Wildcard

Câu trả lời:


2

Spaghetti Stacks có phải là cây bố mẹ?

Vâng, ngăn xếp spaghetti là cây con trỏ cha mẹ. Bạn có thể nghĩ về một ngăn xếp spaghetti có cùng cấu trúc với một tập hợp các danh sách liên kết đơn có chung cấu trúc. Khi được xem như một toàn thể, bộ sưu tập các danh sách tạo thành một cây. Nhưng khi xem riêng lẻ, mỗi danh sách tạo thành một ngăn xếp.

Mỗi quy trình trong hệ thống sẽ có một trong những danh sách này, đại diện cho ngăn xếp điều khiển của nó. Phần đầu của danh sách là phần trên cùng của ngăn xếp (tức là khung hoạt động). Con nexttrỏ của nó tham chiếu khung cha.

Những gì bạn thấy trong sơ đồ là cấu trúc cho nhiều quá trình. Ngăn xếp cho quá trình "hoạt động" được tô sáng. Các phần của cây không phải là một phần của ngăn xếp hoạt động được tô màu xám. Chúng đại diện cho ngăn xếp cho các quá trình khác.

Làm Spaghetti Stacks tạo thành một DAG?

Vì ngăn xếp Spaghetti là cây con trỏ cha mẹ, chúng thực sự là DAG. Nhưng chỉ DAGs cũng là cây có thể là ngăn xếp Spaghetti. Vì vậy, không, các ngăn xếp Spaghetti không tạo thành các DAG không phải là cây.

Ví dụ của bạn về một hàm quyết định kết hợp cấu trúc của ngăn xếp điều khiển với dữ liệu được lưu trữ trong ngăn xếp. Chắc chắn, bất kỳ cấu trúc nào cũng có thể được hình thành nếu chúng ta bắt đầu xem xét dữ liệu. Nhưng là một cơ sở hạ tầng, mỗi nút trong ngăn xếp spaghetti sẽ có chính xác một cha mẹ.

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.