Ngăn xếp cuộc gọi trong C/C++

Ngăn xếp cuộc gọi, trong C #, là danh sách tên của các phương thức được gọi trong thời gian chạy từ khi bắt đầu chương trình cho đến khi thực hiện câu lệnh hiện tại

Ngăn xếp cuộc gọi chủ yếu nhằm mục đích theo dõi điểm mà mỗi chương trình con đang hoạt động sẽ trả lại quyền kiểm soát khi nó kết thúc thực thi. Ngăn xếp cuộc gọi hoạt động như một công cụ để gỡ lỗi ứng dụng khi phương thức được theo dõi có thể được gọi trong nhiều ngữ cảnh. Điều này tạo thành một giải pháp thay thế tốt hơn là thêm mã theo dõi vào tất cả các phương thức gọi phương thức đã cho. Bất cứ khi nào một ngoại lệ được ném vào bất kỳ đâu trong mã người dùng, Common Language Runtime (CLR) sẽ giải phóng ngăn xếp cuộc gọi và tìm kiếm khối catch để xác định loại ngoại lệ cụ thể. Nếu không có trình xử lý phù hợp, CLR sẽ chấm dứt ứng dụng. Do đó, ngăn xếp cuộc gọi được sử dụng để báo cho con trỏ thực thi nơi tiếp theo

Quảng cáo

Techopedia giải thích ngăn xếp cuộc gọi

Ngăn xếp cuộc gọi được tổ chức dưới dạng "ngăn xếp", một cấu trúc dữ liệu trong bộ nhớ để lưu trữ các mục theo cách vào trước ra trước, để người gọi chương trình con đẩy địa chỉ trả về vào ngăn xếp và chương trình con được gọi, sau khi kết thúc,

Trong C#, bất kỳ ứng dụng nào cũng bắt đầu bằng phương thức "chính", phương thức này sẽ gọi các phương thức khác. Trên mỗi lần gọi một phương thức, phương thức đó được thêm vào đầu ngăn xếp và bị xóa khỏi ngăn xếp khi nó quay trở lại trình gọi. Ngoài ra, phạm vi của một biến được khai báo trong một khối được xác định từ thời điểm giá trị của nó được đẩy vào ngăn xếp (như một phần của ngăn xếp cuộc gọi) cho đến khi việc thực thi rời khỏi khối khi biến và ngăn xếp cuộc gọi được bật ra khỏi ngăn xếp. Do đó, ngăn xếp duy trì cả biến cục bộ (loại giá trị) và ngăn xếp cuộc gọi (khung ngăn xếp), kích thước cho biết độ phức tạp của chương trình

Ngăn xếp cuộc gọi là một loạt các địa chỉ bộ đếm chương trình (PC) đại diện cho các hướng dẫn từ bên trong chương trình. PC đầu tiên, được gọi là PC lá, nằm ở dưới cùng của ngăn xếp và là địa chỉ của lệnh tiếp theo sẽ được thực hiện. PC tiếp theo là địa chỉ của lệnh gọi hàm chứa PC lá; . Mỗi địa chỉ như vậy được gọi là địa chỉ trả lại. Quá trình ghi lại ngăn xếp cuộc gọi liên quan đến việc lấy địa chỉ trả về từ ngăn xếp chương trình và được gọi là giải phóng ngăn xếp. Để biết thông tin về các lỗi thư giãn, xem Uncomplete Stack Unwinds

PC lá trong ngăn xếp cuộc gọi được sử dụng để chỉ định các số liệu độc quyền từ dữ liệu hiệu suất cho chức năng mà PC đó được đặt. Mỗi PC trên ngăn xếp, bao gồm cả PC lá, được sử dụng để gán các chỉ số bao gồm cho chức năng chứa nó

Hầu hết thời gian, các PC trong ngăn xếp cuộc gọi được ghi lại tương ứng một cách tự nhiên với các chức năng khi chúng xuất hiện trong mã nguồn của chương trình và các chỉ số được báo cáo của Trình phân tích hiệu suất tương ứng trực tiếp với các chức năng đó. Tuy nhiên, đôi khi, việc thực thi chương trình thực tế không tương ứng với một mô hình trực quan đơn giản về cách chương trình sẽ thực thi và các chỉ số được báo cáo của Trình phân tích hiệu suất có thể gây nhầm lẫn. Xem Địa chỉ ánh xạ tới Cấu trúc chương trình để biết thêm thông tin về các trường hợp như vậy

Lệnh gọi chức năng và thực thi đơn luồng

Trường hợp thực thi chương trình đơn giản nhất là chương trình đơn luồng gọi các hàm bên trong đối tượng tải của chính nó

Khi một chương trình được tải vào bộ nhớ để bắt đầu thực hiện, một ngữ cảnh được thiết lập cho chương trình bao gồm địa chỉ ban đầu sẽ được thực thi, bộ thanh ghi ban đầu và ngăn xếp (một vùng bộ nhớ được sử dụng cho dữ liệu đầu và để theo dõi hoạt động của các chức năng). . Địa chỉ ban đầu luôn ở đầu hàm _start(), được tích hợp trong mọi tệp thực thi

Khi chương trình chạy, các lệnh được thực hiện theo trình tự cho đến khi gặp lệnh rẽ nhánh, lệnh này trong số những thứ khác có thể biểu thị lệnh gọi hàm hoặc câu lệnh điều kiện. Tại điểm nhánh, quyền điều khiển được chuyển đến địa chỉ được cung cấp bởi mục tiêu của nhánh và việc thực thi được tiến hành từ đó. (Thông thường lệnh tiếp theo sau khi nhánh đã được cam kết thực hiện. hướng dẫn này được gọi là hướng dẫn khe trễ nhánh. Tuy nhiên, một số hướng dẫn nhánh hủy bỏ việc thực hiện hướng dẫn khe trễ nhánh)

Khi chuỗi lệnh đại diện cho một lệnh gọi được thực thi, địa chỉ trả về được đưa vào một thanh ghi và quá trình thực thi diễn ra ở lệnh đầu tiên của hàm được gọi

Trong hầu hết các trường hợp, ở đâu đó trong một vài lệnh đầu tiên của hàm được gọi, một khung mới (vùng bộ nhớ được sử dụng để lưu trữ thông tin về hàm) được đẩy lên ngăn xếp và địa chỉ trả về được đặt vào khung đó. Sau đó, thanh ghi được sử dụng cho địa chỉ trả về có thể được sử dụng khi chính chức năng được gọi gọi một chức năng khác. Khi chức năng chuẩn bị trả về, nó sẽ bật khung của nó khỏi ngăn xếp và điều khiển quay trở lại địa chỉ mà chức năng được gọi

Các cuộc gọi chức năng giữa các đối tượng được chia sẻ

Khi một hàm trong một đối tượng được chia sẻ gọi một hàm trong một đối tượng được chia sẻ khác, thì việc thực thi phức tạp hơn so với một lệnh gọi đơn giản tới một hàm trong chương trình. Mỗi đối tượng được chia sẻ chứa Bảng liên kết chương trình hoặc PLT, chứa các mục nhập cho mọi chức năng bên ngoài đối tượng được chia sẻ đó được tham chiếu từ nó. Ban đầu, địa chỉ cho mỗi chức năng bên ngoài trong PLT thực sự là một địa chỉ trong ld. vì vậy, trình liên kết động. Lần đầu tiên một chức năng như vậy được gọi, quyền điều khiển được chuyển đến trình liên kết động, trình này sẽ giải quyết cuộc gọi đến chức năng bên ngoài thực và vá địa chỉ PLT cho các cuộc gọi tiếp theo

Nếu một sự kiện lập hồ sơ xảy ra trong quá trình thực hiện một trong ba lệnh PLT, các PC PLT sẽ bị xóa và thời gian dành riêng được quy cho lệnh gọi. Nếu một sự kiện lập hồ sơ xảy ra trong cuộc gọi đầu tiên thông qua mục nhập PLT, nhưng PC lá không phải là một trong các hướng dẫn PLT, bất kỳ PC nào phát sinh từ PLT và mã trong ld. so được thay thế bằng lệnh gọi hàm nhân tạo, @plt, tích lũy thời gian bao hàm. Có một chức năng nhân tạo như vậy cho mỗi đối tượng được chia sẻ. Nếu chương trình sử dụng giao diện LD_AUDIT, các mục PLT có thể không bao giờ được vá và các PC không lá từ @plt có thể xảy ra thường xuyên hơn

tín hiệu

Khi một tín hiệu được gửi đến một tiến trình, các hoạt động thanh ghi và ngăn xếp khác nhau sẽ xảy ra khiến cho nó trông như thể PC lá tại thời điểm của tín hiệu là địa chỉ trả về cho lệnh gọi đến một chức năng hệ thống, sigacthandler(). sigacthandler() gọi trình xử lý tín hiệu do người dùng chỉ định giống như bất kỳ hàm nào sẽ gọi một hàm khác

Trình phân tích hiệu suất xử lý các khung do phân phối tín hiệu như các khung thông thường. Mã người dùng tại điểm tín hiệu được gửi được hiển thị khi gọi chức năng hệ thống sigacthandler() và đến lượt sigacthandler() được hiển thị khi gọi trình xử lý tín hiệu của người dùng. Chỉ số bao gồm từ cả sigacthandler() và bất kỳ trình xử lý tín hiệu người dùng nào cũng như bất kỳ hàm nào khác mà chúng gọi, xuất hiện dưới dạng chỉ số bao gồm cho hàm bị gián đoạn

Collector xen vào sigaction() để đảm bảo rằng các trình xử lý của nó là trình xử lý chính cho tín hiệu SIGPROF khi dữ liệu đồng hồ được thu thập và tín hiệu SIGEMT khi dữ liệu tràn bộ đếm phần cứng được thu thập

bẫy

Bẫy có thể được đưa ra bởi một hướng dẫn hoặc bởi phần cứng và được bắt bởi một trình xử lý bẫy. Bẫy hệ thống là bẫy được bắt đầu từ một lệnh và bẫy vào nhân. Tất cả các cuộc gọi hệ thống được thực hiện bằng cách sử dụng lệnh bẫy. Một số ví dụ về bẫy phần cứng là những bẫy được phát ra từ đơn vị dấu phẩy động khi nó không thể hoàn thành một lệnh (chẳng hạn như lệnh fitos cho một số giá trị nội dung thanh ghi trên nền tảng UltraSPARC® III) hoặc khi lệnh không được triển khai trong

Khi bẫy được đưa ra, nhân Linux hoặc LWP của Solaris sẽ chuyển sang chế độ hệ thống. Trên hệ điều hành Solaris, trạng thái vi mô thường được chuyển từ trạng thái CPU của người dùng sang trạng thái Bẫy rồi sang trạng thái Hệ thống. Thời gian dành cho việc xử lý bẫy có thể hiển thị dưới dạng kết hợp giữa thời gian của CPU Hệ thống và thời gian của CPU Người dùng, tùy thuộc vào thời điểm mà trạng thái vi mô được chuyển đổi. Thời gian được quy cho hướng dẫn trong mã của người dùng mà từ đó bẫy được bắt đầu (hoặc cho lệnh gọi hệ thống)

Đối với một số cuộc gọi hệ thống, điều quan trọng là cung cấp khả năng xử lý cuộc gọi hiệu quả nhất có thể. Các bẫy được tạo bởi các cuộc gọi này được gọi là bẫy nhanh. Trong số các chức năng hệ thống tạo bẫy nhanh là gethrtime và gethrvtime. Trong các chức năng này, trạng thái vi mô không được chuyển đổi do có liên quan đến chi phí

Trong các trường hợp khác, việc xử lý bẫy hiệu quả nhất có thể cũng được coi là rất quan trọng. Một số ví dụ trong số này là lỗi TLB (bộ đệm tra cứu dịch thuật) và đăng ký tràn và lấp đầy cửa sổ, trong đó trạng thái vi mô không được chuyển đổi

Trong cả hai trường hợp, thời gian sử dụng được ghi là thời gian CPU của người dùng. Tuy nhiên, bộ đếm phần cứng bị tắt vì chế độ CPU đã được chuyển sang chế độ hệ thống. Do đó, thời gian dành cho việc xử lý các bẫy này có thể được ước tính bằng cách lấy chênh lệch giữa thời gian CPU của Người dùng và thời gian Chu kỳ, tốt nhất là được ghi lại trong cùng một thử nghiệm

Trong một trường hợp, trình xử lý bẫy chuyển về chế độ người dùng và đó là bẫy tham chiếu bộ nhớ bị lệch cho một số nguyên 8 byte được căn chỉnh trên ranh giới 4 byte trong Fortran. Một khung dành cho trình xử lý bẫy xuất hiện trên ngăn xếp và lệnh gọi đến trình xử lý có thể xuất hiện trong Trình phân tích hiệu suất, được quy cho lệnh tải số nguyên hoặc lệnh lưu trữ

Khi một lệnh bẫy vào kernel, lệnh theo sau lệnh bẫy có vẻ mất nhiều thời gian, vì nó không thể bắt đầu cho đến khi kernel thực hiện xong lệnh bẫy

Tối ưu hóa cuộc gọi đuôi

Trình biên dịch có thể thực hiện một tối ưu hóa cụ thể bất cứ khi nào điều cuối cùng mà một chức năng cụ thể thực hiện là gọi một chức năng khác. Thay vì tạo một khung mới, callee sử dụng lại khung từ người gọi và địa chỉ trả về cho callee được sao chép từ người gọi. Động lực cho việc tối ưu hóa này là để giảm kích thước của ngăn xếp và, trên các nền tảng SPARC, để giảm việc sử dụng các cửa sổ đăng ký

Giả sử rằng chuỗi cuộc gọi trong nguồn chương trình của bạn trông như thế này

A -> B -> C -> D

Khi B và C được tối ưu hóa cuộc gọi đuôi, ngăn xếp cuộc gọi trông giống như chức năng A gọi trực tiếp các chức năng B, C và D

A -> B
A -> C
A -> D

Đó là, cây cuộc gọi bị san bằng. Khi mã được biên dịch với tùy chọn -g, việc tối ưu hóa cuộc gọi đuôi chỉ diễn ra ở mức tối ưu hóa trình biên dịch từ 4 trở lên. Khi mã được biên dịch mà không có tùy chọn the- g, việc tối ưu hóa cuộc gọi đuôi diễn ra ở mức tối ưu hóa trình biên dịch từ 2 trở lên

Đa luồng rõ ràng

Một chương trình đơn giản thực thi trong một luồng đơn, trên một LWP (quy trình nhẹ) duy nhất trong Hệ điều hành Solaris. Các tệp thực thi đa luồng thực hiện các cuộc gọi đến chức năng tạo luồng, chức năng đích để thực thi được chuyển đến. Khi mục tiêu thoát, luồng bị hủy

Hệ điều hành Solaris hỗ trợ triển khai hai luồng. Chủ đề Solaris và chủ đề POSIX (Pthreads). Bắt đầu với Hệ điều hành Solaris 10, cả hai cách triển khai luồng đều được bao gồm trong libc. Vì thế

Với các luồng Solaris, các luồng mới được tạo bắt đầu thực thi tại một hàm có tên _thread_start(), hàm này gọi hàm được truyền trong lệnh gọi tạo luồng. Đối với bất kỳ ngăn xếp cuộc gọi nào liên quan đến mục tiêu được thực thi bởi luồng này, đỉnh của ngăn xếp là _thread_start() và không có kết nối với người gọi chức năng tạo luồng. Do đó, các chỉ số bao gồm được liên kết với chuỗi đã tạo chỉ lan truyền đến _thread_start() và hàm. Ngoài việc tạo các luồng, việc triển khai các luồng Solaris cũng tạo các LWP trên Solaris để thực thi các luồng. Mỗi luồng được liên kết với một LWP cụ thể

Pthreads có sẵn trong HĐH Solaris 10 cũng như trong HĐH Linux để xử lý đa luồng rõ ràng

Trong cả hai môi trường, để tạo một luồng mới, ứng dụng gọi hàm API Pthread pthread_create(), chuyển một con trỏ tới một quy trình bắt đầu do ứng dụng xác định làm một trong các đối số của hàm

Trên hệ điều hành Solaris, khi một pthread mới bắt đầu thực thi, nó gọi hàm _lwp_start(). Trên hệ điều hành Solaris 10, _lwp_start() gọi hàm trung gian _thr_setup(), hàm này sau đó gọi quy trình bắt đầu do ứng dụng xác định đã được chỉ định trong pthread_create()

Trên hệ điều hành Linux, khi pthread mới bắt đầu thực thi, nó sẽ chạy một chức năng hệ thống dành riêng cho Linux, clone(), gọi một chức năng khởi tạo bên trong khác, pthread_start_thread(), đến lượt nó gọi thủ tục bắt đầu do ứng dụng xác định đã được chỉ định trong . Các chức năng thu thập số liệu Linux có sẵn cho Collector dành riêng cho từng luồng. Do đó, khi tiện ích thu thập chạy, nó sẽ đặt một hàm thu thập số liệu, có tên là collector_root(), giữa pthread_start_thread() và quy trình bắt đầu luồng do ứng dụng xác định

Tổng quan về thực thi phần mềm dựa trên công nghệ Java

Đối với nhà phát triển điển hình, một ứng dụng dựa trên công nghệ Java chạy giống như bất kỳ chương trình nào khác. Ứng dụng bắt đầu tại một điểm vào chính, thường được đặt tên là lớp. main, có thể gọi các phương thức khác, giống như ứng dụng C hoặc C++

Đối với hệ điều hành, một ứng dụng được viết bằng ngôn ngữ lập trình Java, (thuần túy hoặc trộn lẫn với C/C++), chạy như một quá trình khởi tạo phần mềm JVM. Phần mềm JVM được biên dịch từ các nguồn C++ và bắt đầu thực thi tại _start, gọi hàm main, v.v. Nó đọc bytecode từ. lớp và/hoặc. jar và thực hiện các thao tác được chỉ định trong chương trình đó. Trong số các hoạt động có thể được chỉ định là tải động của một đối tượng được chia sẻ riêng và gọi các hàm hoặc phương thức khác nhau có trong đối tượng đó

Phần mềm JVM thực hiện một số việc thường không được thực hiện bởi các ứng dụng được viết bằng ngôn ngữ truyền thống. Khi khởi động, nó tạo ra một số vùng mã được tạo động trong không gian dữ liệu của nó. Một trong những vùng này là mã trình thông dịch thực tế được sử dụng để xử lý các phương thức mã byte của ứng dụng

Trong quá trình thực thi ứng dụng dựa trên công nghệ Java, hầu hết các phương thức đều được giải thích bởi phần mềm JVM; . Máy ảo Java HotSpot giám sát hiệu suất khi nó diễn giải mã byte để phát hiện các phương thức được thực thi thường xuyên. Sau đó, các phương thức được thực thi lặp lại có thể được máy ảo Java HotSpot biên dịch để tạo mã máy cho các phương thức đó. Các phương pháp kết quả được gọi là phương pháp biên dịch. Máy ảo thực thi các phương thức được biên dịch hiệu quả hơn sau đó, thay vì diễn giải mã byte gốc cho các phương thức. Các phương thức đã biên dịch được tải vào không gian dữ liệu của ứng dụng và có thể được dỡ tải vào một thời điểm nào đó sau này. Ngoài ra, mã khác được tạo trong không gian dữ liệu để thực hiện quá trình chuyển đổi giữa mã được giải thích và biên dịch

Mã được viết bằng ngôn ngữ lập trình Java cũng có thể gọi trực tiếp vào mã được biên dịch riêng, C, C++ hoặc Fortran;

Các ứng dụng được viết bằng ngôn ngữ lập trình Java vốn đã đa luồng và có một luồng phần mềm JVM cho mỗi luồng trong chương trình của người dùng. Các ứng dụng Java cũng có một số luồng quản lý được sử dụng để xử lý tín hiệu, quản lý bộ nhớ và biên dịch máy ảo Java HotSpot

Việc thu thập dữ liệu được triển khai bằng nhiều phương thức khác nhau trong JVMTI trong J2SE 5. 0

Ngăn xếp cuộc gọi Java và ngăn xếp cuộc gọi máy

Các công cụ hiệu suất thu thập dữ liệu của chúng bằng cách ghi lại các sự kiện trong vòng đời của mỗi luồng Solaris LWP hoặc Linux, cùng với ngăn xếp cuộc gọi tại thời điểm xảy ra sự kiện. Tại bất kỳ thời điểm nào trong quá trình thực thi bất kỳ ứng dụng nào, ngăn xếp cuộc gọi biểu thị nơi chương trình đang thực thi và cách nó đến đó. Một điểm quan trọng mà các ứng dụng Java mô hình hỗn hợp khác với các ứng dụng C, C++ và Fortran truyền thống là tại bất kỳ thời điểm nào trong quá trình chạy mục tiêu, có hai ngăn xếp cuộc gọi có ý nghĩa. ngăn xếp cuộc gọi Java và ngăn xếp cuộc gọi máy. Cả hai ngăn xếp cuộc gọi đều được ghi lại trong quá trình lập hồ sơ và được đối chiếu trong quá trình phân tích

Hồ sơ dựa trên đồng hồ và Hồ sơ tràn bộ đếm phần cứng

Cấu hình dựa trên đồng hồ và cấu hình tràn bộ đếm phần cứng cho các chương trình Java hoạt động giống như đối với các chương trình C, C++ và Fortran, ngoại trừ cả ngăn xếp cuộc gọi Java và ngăn xếp cuộc gọi máy đều được thu thập

Biểu diễn xử lý Java

Có ba cách biểu diễn để hiển thị dữ liệu hiệu suất cho các ứng dụng được viết bằng ngôn ngữ lập trình Java. biểu diễn Java, biểu diễn Expert-Java và biểu diễn Máy. Biểu diễn Java được hiển thị theo mặc định nơi dữ liệu hỗ trợ nó. Phần sau đây tóm tắt sự khác biệt chính giữa ba đại diện này

Đại diện người dùng

Biểu diễn Người dùng hiển thị các phương thức Java được biên dịch và giải thích theo tên và hiển thị các phương thức gốc ở dạng tự nhiên của chúng. Trong quá trình thực thi, có thể có nhiều phiên bản của một phương thức Java cụ thể được thực thi. phiên bản được giải thích và, có lẽ, một hoặc nhiều phiên bản được biên dịch. Trong biểu diễn Java, tất cả các phương thức được hiển thị tổng hợp dưới dạng một phương thức duy nhất. Biểu diễn này được chọn trong Trình phân tích theo mặc định

Một PC cho phương thức Java trong biểu diễn Java tương ứng với id phương thức và chỉ mục mã byte cho phương thức đó; . Ngăn xếp cuộc gọi cho luồng Java có thể có sự kết hợp giữa PC Java và PC máy. Nó không có bất kỳ khung nào tương ứng với mã quản lý Java, không có biểu diễn Java. Trong một số trường hợp, phần mềm JVM không thể giải phóng ngăn xếp Java và một khung duy nhất có chức năng đặc biệt, , được trả về. Thông thường, nó chiếm không quá 5-10% tổng thời gian

Danh sách hàm trong biểu diễn Java hiển thị các số liệu đối với các phương thức Java và bất kỳ phương thức gốc nào được gọi là. Bảng gọi-callee hiển thị các mối quan hệ gọi trong biểu diễn Java

Nguồn cho một phương thức Java tương ứng với mã nguồn trong. java mà nó được biên dịch từ đó, với các số liệu trên mỗi dòng nguồn. Việc tháo gỡ bất kỳ phương thức Java nào sẽ hiển thị mã byte được tạo cho nó, với các số liệu đối với từng mã byte và nguồn Java xen kẽ, nếu có

Dòng thời gian trong biểu diễn Java chỉ hiển thị các luồng Java. Ngăn xếp cuộc gọi cho mỗi luồng được hiển thị với các phương thức Java của nó

Cấu hình không gian dữ liệu trong biểu diễn Java hiện không được hỗ trợ

Đại diện chuyên gia-người dùng

Biểu diễn Expert-Java tương tự như Biểu diễn Java, ngoại trừ một số chi tiết của phần bên trong JVM bị chặn trong Biểu diễn Java được hiển thị trong Biểu diễn Expert-Java. Với đại diện Expert-Java, Dòng thời gian hiển thị tất cả các luồng;

Đại diện máy

Biểu diễn Máy hiển thị các chức năng từ chính phần mềm JVM, chứ không phải từ ứng dụng được giải thích bởi phần mềm JVM. Nó cũng hiển thị tất cả các phương thức được biên dịch và bản địa. Biểu diễn máy trông giống như biểu diễn của các ứng dụng được viết bằng ngôn ngữ truyền thống. Ngăn xếp cuộc gọi hiển thị các khung JVM, khung gốc và khung phương thức đã biên dịch. Một số khung JVM biểu thị mã chuyển đổi giữa Java được giải thích, Java được biên dịch và mã gốc

Nguồn từ các phương thức đã biên dịch được hiển thị dựa trên nguồn Java; . Việc tháo gỡ cho các phương thức đã biên dịch hiển thị mã trình biên dịch chương trình máy được tạo, không phải mã byte Java. Mối quan hệ giữa người gọi và người gọi hiển thị tất cả các khung trên cao và tất cả các khung biểu thị quá trình chuyển đổi giữa các phương thức được giải thích, biên dịch và gốc

Dòng thời gian trong biểu diễn máy hiển thị các thanh cho tất cả các luồng, LWP hoặc CPU và ngăn xếp cuộc gọi trong mỗi ngăn xếp cuộc gọi đại diện cho máy

Tổng quan về thực thi phần mềm OpenMP

Mô hình thực thi thực tế của Ứng dụng OpenMP được mô tả trong thông số kỹ thuật của OpenMP (Ví dụ, xem Giao diện chương trình ứng dụng OpenMP, Phiên bản 3. 0, phần 1. 3. ) Tuy nhiên, đặc điểm kỹ thuật không mô tả một số chi tiết triển khai có thể quan trọng đối với người dùng và việc triển khai thực tế tại Sun Microsystems khiến thông tin lược tả được ghi trực tiếp không dễ dàng cho phép người dùng hiểu cách các luồng tương tác

Khi bất kỳ chương trình đơn luồng nào chạy, ngăn xếp cuộc gọi của nó hiển thị vị trí hiện tại của nó và dấu vết về cách nó đến đó, bắt đầu từ các hướng dẫn ban đầu trong một quy trình có tên _start, lệnh gọi chính, sau đó tiếp tục và gọi các chương trình con khác nhau trong chương trình. Khi một chương trình con chứa một vòng lặp, chương trình sẽ thực thi mã bên trong vòng lặp lặp đi lặp lại cho đến khi đạt được tiêu chí thoát khỏi vòng lặp. Sau đó, quá trình thực thi sẽ tiếp tục với chuỗi mã tiếp theo, v.v.

Khi chương trình được song song hóa với OpenMP (hoặc bằng cách tự động song song hóa), hành vi sẽ khác. Một mô hình trực quan của hành vi đó có luồng chính hoặc chủ, thực thi giống như một chương trình đơn luồng. Khi nó đến một vòng lặp song song hoặc vùng song song, các luồng phụ bổ sung sẽ xuất hiện, mỗi luồng phụ là một bản sao của luồng chính, với tất cả chúng thực thi nội dung của vòng lặp hoặc vùng song song, song song, mỗi luồng cho các khối công việc khác nhau. Khi tất cả các khối công việc được hoàn thành, tất cả các luồng được đồng bộ hóa, các luồng phụ biến mất và luồng chính tiếp tục

Khi trình biên dịch tạo mã cho một vùng hoặc vòng lặp song song (hoặc bất kỳ cấu trúc OpenMP nào khác), mã bên trong nó được trích xuất và tạo thành một hàm độc lập, được gọi là mfunction. (Nó cũng có thể được gọi là một hàm được phác thảo, hoặc một hàm vòng lặp. ) Tên của hàm mã hóa loại cấu trúc OpenMP, tên của hàm mà nó được trích xuất và số dòng của dòng nguồn nơi cấu trúc xuất hiện. Tên của các hàm này được hiển thị trong Trình phân tích ở dạng sau, trong đó tên trong ngoặc là tên bảng ký hiệu thực của hàm

bardo_ -- OMP parallel region from line 9 [_$p1C9.bardo_]
atomsum_ -- MP doall from line 7 [_$d1A7.atomsum_]

Có các dạng khác của các chức năng như vậy, bắt nguồn từ các cấu trúc nguồn khác, trong đó vùng song song OMP trong tên được thay thế bằng cấu trúc MP, MP doall hoặc phần OMP. Trong cuộc thảo luận sau đây, tất cả những thứ này được gọi chung là "các vùng song song"

Mỗi luồng thực thi mã trong vòng lặp song song có thể gọi mfunction của nó nhiều lần, với mỗi lần gọi thực hiện một đoạn công việc trong vòng lặp. Khi tất cả các khối công việc hoàn tất, mỗi luồng gọi các thủ tục đồng bộ hóa hoặc rút gọn trong thư viện; . Tất cả việc lên lịch và đồng bộ hóa được xử lý bằng các cuộc gọi đến thời gian chạy OpenMP

Trong quá trình thực thi, mã trong vùng song song có thể đang thực hiện một đoạn công việc hoặc nó có thể đang đồng bộ hóa với các luồng khác hoặc chọn thêm các đoạn công việc cần thực hiện. Nó cũng có thể gọi các chức năng khác, đến lượt nó có thể gọi các chức năng khác. Một luồng phụ (hoặc luồng chính) thực thi trong một vùng song song, có thể chính nó hoặc từ một chức năng mà nó gọi, hoạt động như một luồng chính và đi vào vùng song song của chính nó, dẫn đến song song lồng nhau

Trình phân tích thu thập dữ liệu dựa trên lấy mẫu thống kê của ngăn xếp cuộc gọi, đồng thời tổng hợp dữ liệu của nó trên tất cả các luồng và hiển thị số liệu về hiệu suất dựa trên loại dữ liệu được thu thập, đối với chức năng, người gọi và người được gọi, dòng nguồn và hướng dẫn. Nó trình bày thông tin về hiệu suất của các chương trình OpenMP ở một trong ba chế độ, Chế độ người dùng , Chế độ chuyên gia và Chế độ máy

Để biết thêm thông tin chi tiết, hãy xem An OpenMP Runtime API for Profiling tại trang web cộng đồng người dùng OpenMP

Chế độ người dùng Hiển thị dữ liệu hồ sơ OpenMP

Trình bày chế độ Người dùng của dữ liệu hồ sơ cố gắng trình bày thông tin như thể chương trình thực sự được thực thi theo mô hình được mô tả trong Tổng quan về Thực thi Phần mềm OpenMP. Dữ liệu thực tế ghi lại chi tiết triển khai của thư viện thời gian chạy, libmtsk. so , không tương ứng với mô hình. Trong chế độ Người dùng, cách trình bày dữ liệu hồ sơ được thay đổi để phù hợp hơn với mô hình và khác với cách trình bày dữ liệu được ghi và Chế độ máy theo ba cách

  • Các chức năng nhân tạo được xây dựng đại diện cho trạng thái của từng luồng theo quan điểm của thư viện thời gian chạy OpenMP

  • Ngăn xếp cuộc gọi được thao tác để báo cáo dữ liệu tương ứng với mô hình về cách mã chạy, như được mô tả ở trên

  • Hai chỉ số hiệu suất bổ sung được xây dựng cho các thử nghiệm lập hồ sơ dựa trên đồng hồ, tương ứng với thời gian dành cho công việc hữu ích và thời gian chờ đợi trong thời gian chạy OpenMP

Chức năng nhân tạo

Các chức năng nhân tạo được xây dựng và đưa vào ngăn xếp lệnh gọi Chế độ người dùng phản ánh các sự kiện trong đó một chuỗi ở trạng thái nào đó trong thư viện thời gian chạy OpenMP

Các chức năng nhân tạo sau đây được xác định

Thực thi trong thư viện OpenMP

Chủ đề nô lệ, chờ đợi công việc

Chủ đề thực hiện một hoạt động giảm

Chủ đề chờ đợi ở một rào cản ngầm

Chủ đề đang chờ ở một rào cản rõ ràng

Chủ đề đang chờ khóa

Chủ đề đang chờ để vào phần quan trọng

Chủ đề chờ đến lượt vào phần được sắp xếp

Khi một luồng ở trạng thái thời gian chạy OpenMP tương ứng với một trong các hàm đó, hàm tương ứng sẽ được thêm dưới dạng hàm lá trên ngăn xếp. Khi chức năng lá của luồng ở bất kỳ đâu trong thời gian chạy OpenMP, nó sẽ được thay thế bằng chức năng lá. Nếu không, tất cả các PC từ thời gian chạy OpenMP sẽ bị bỏ qua khỏi ngăn xếp chế độ người dùng

Ngăn xếp cuộc gọi chế độ người dùng

Đối với thử nghiệm OpenMP, chế độ người dùng hiển thị ngăn xếp cuộc gọi được xây dựng lại tương tự như ngăn xếp thu được khi chương trình được biên dịch mà không có OpenMP

Số liệu OpenMP

Khi xử lý sự kiện hồ sơ đồng hồ cho chương trình OpenMP, hai số liệu tương ứng với thời gian dành cho mỗi hai trạng thái trong hệ thống OpenMP được hiển thị. OpenMP làm việc và OpenMP chờ

Thời gian được tích lũy trong OpenMP Work bất cứ khi nào một luồng đang thực thi từ mã người dùng, cho dù là nối tiếp hay song song. Thời gian được tích lũy trong OpenMP Chờ bất cứ khi nào một luồng đang chờ một thứ gì đó trước khi nó có thể tiếp tục, cho dù thời gian chờ là chờ bận (chờ quay) hay đang ngủ. Tổng của hai chỉ số này khớp với chỉ số Tổng thời gian LWP trong cấu hình đồng hồ

Máy trình bày dữ liệu cấu hình OpenMP

Ngăn xếp cuộc gọi thực sự của chương trình trong các giai đoạn thực thi khác nhau hoàn toàn khác với ngăn xếp được mô tả ở trên trong mô hình trực quan. Chế độ trình bày Máy hiển thị ngăn xếp cuộc gọi như đã đo, không thực hiện chuyển đổi nào và không xây dựng chức năng nhân tạo nào. Tuy nhiên, các số liệu định hình đồng hồ vẫn được hiển thị

Trong mỗi ngăn xếp cuộc gọi bên dưới, libmtsk đại diện cho một hoặc nhiều khung trong ngăn xếp cuộc gọi trong thư viện thời gian chạy OpenMP. Chi tiết về chức năng nào xuất hiện và thứ tự thay đổi từ bản phát hành này sang bản phát hành khác, cũng như việc triển khai mã nội bộ cho rào cản hoặc để thực hiện giảm bớt

  1. Trước khu vực song song đầu tiên

    Trước khi vùng song song đầu tiên được nhập, chỉ có một luồng, luồng chính. Ngăn xếp cuộc gọi giống hệt với ngăn xếp trong chế độ Người dùng

  2. Trong khi thực hiện trong một khu vực song song

    Sư phụ

    nô lệ 1

    nô lệ 2

    nô lệ 3

    foo-OMP

    libmtsk

    foo

    foo-OMP

    foo-OMP

    foo-OMP

    chủ yếu

    libmtsk

    libmtsk

    libmtsk

    _bắt đầu

    _lwp_start

    _lwp_start

    _lwp_start

    Ở chế độ Máy, các chuỗi phụ được hiển thị là bắt đầu trong _lwp_start , thay vì trong _start nơi chủ bắt đầu. (Trong một số phiên bản của thư viện luồng, chức năng đó có thể xuất hiện dưới dạng _thread_start. )

  3. Tại điểm mà tất cả các chủ đề đều ở một rào cản

    Sư phụ

    nô lệ 1

    nô lệ 2

    nô lệ 3

    libmtsk

    foo-OMP

    foo

    libmtsk

    libmtsk

    libmtsk

    chủ yếu

    foo-OMP

    foo-OMP

    foo-OMP

    _bắt đầu

    _lwp_start

    _lwp_start

    _lwp_start

    Không giống như khi các luồng đang thực thi ở vùng song song, khi các luồng đang đợi ở một hàng rào, không có khung nào từ thời gian chạy OpenMP giữa foo và mã vùng song song, foo-OMP. Lý do là việc thực thi thực tế không bao gồm chức năng vùng song song OMP, nhưng thời gian chạy OpenMP điều khiển các thanh ghi để ngăn xếp thư giãn hiển thị lệnh gọi từ chức năng vùng song song được thực hiện lần cuối tới mã rào cản thời gian chạy. Không có nó, sẽ không có cách nào để xác định vùng song song nào có liên quan đến cuộc gọi rào cản trong chế độ Máy

  4. Sau khi rời khỏi khu vực song song

    Sư phụ

    nô lệ 1

    nô lệ 2

    nô lệ 3

    foo

    chủ yếu

    libmtsk

    libmtsk

    libmtsk

    _bắt đầu

    _lwp_start

    _lwp_start

    _lwp_start

    Trong chuỗi phụ, không có khung người dùng nào trong ngăn xếp cuộc gọi

  5. Khi ở trong một khu vực song song lồng nhau

    Sư phụ

    nô lệ 1

    nô lệ 2

    nô lệ 3

    nô lệ 4

    thanh-OMP

    foo-OMP

    libmtsk

    libmtsk

    quán ba

    foo

    foo-OMP

    foo-OMP

    foo-OMP

    thanh-OMP

    chủ yếu

    libmtsk

    libmtsk

    libmtsk

    libmtsk

    _bắt đầu

    _lwp_start

    _lwp_start

    _lwp_start

    _lwp_start

Unwinds ngăn xếp không đầy đủ

Ngăn xếp thư giãn có thể thất bại vì một số lý do

  • Nếu ngăn xếp đã bị hỏng bởi mã người dùng;

  • Nếu mã người dùng không tuân theo các quy ước ABI tiêu chuẩn cho các lệnh gọi hàm. Đặc biệt, trên nền tảng SPARC, nếu thanh ghi trả về, %o7, bị thay đổi trước khi lệnh lưu được thực hiện

    Trên bất kỳ nền tảng nào, mã biên dịch mã viết tay có thể vi phạm các quy ước

  • Nếu lá PC ở trong một hàm sau khi khung của callee được lấy ra khỏi ngăn xếp, nhưng trước khi hàm trả về

  • Nếu ngăn xếp cuộc gọi chứa nhiều hơn khoảng 250 khung, Bộ sưu tập không có không gian để giải phóng hoàn toàn ngăn xếp cuộc gọi. Trong trường hợp này, PC cho các chức năng từ _start đến một điểm nào đó trong ngăn xếp cuộc gọi không được ghi lại trong thử nghiệm. Chức năng nhân tạo được hiển thị như được gọi từ để kiểm đếm các khung hình trên cùng được ghi lại

  • Nếu Collector không thể giải phóng khung của các chức năng được tối ưu hóa trên nền tảng x86

Tệp trung gian

Nếu bạn tạo các tệp trung gian bằng các tùy chọn trình biên dịch -E hoặc -P, Trình phân tích sẽ sử dụng tệp trung gian cho mã nguồn được chú thích, không phải tệp nguồn gốc. Các lệnh #line được tạo bằng -E có thể gây ra sự cố khi gán số liệu cho các dòng nguồn

Dòng sau xuất hiện trong nguồn được chú thích nếu có hướng dẫn từ hàm không có số dòng đề cập đến tệp nguồn được biên dịch để tạo hàm

function_name -- 

Số dòng có thể vắng mặt trong các trường hợp sau

  • Bạn đã biên dịch mà không chỉ định tùy chọn -g

  • Thông tin gỡ lỗi đã bị loại bỏ sau khi biên dịch hoặc tệp thực thi hoặc tệp đối tượng chứa thông tin được di chuyển hoặc xóa hoặc sửa đổi sau đó

  • Hàm chứa mã được tạo từ các tệp #incoide chứ không phải từ tệp nguồn ban đầu

  • Ở mức tối ưu hóa cao, nếu mã được nội tuyến từ một hàm trong một tệp khác

  • Tệp nguồn có các chỉ thị #line đề cập đến một số tệp khác; . tôi tập tin là một cách mà điều này xảy ra. Nó cũng có thể xảy ra khi bạn biên dịch với cờ -P

    Ngăn xếp cuộc gọi trong C là gì?

    Gọi Stack trong C là gì? . Nhiệm vụ chính của Function Call Stack trong C là quản lý các lời gọi hàm và cách chúng truyền tham số cho nhau. Một ngăn xếp cuộc gọi được duy trì cho từng tác vụ và cho từng luồng. a dynamic data structure maintained inside the RAM memory by the Operating System. Primary task of Function Call Stack in C is to manage the function calls and how they pass parameters to each other. A call stack is maintained for each task and for each thread.

    Ngăn xếp cuộc gọi phương thức là gì?

    Ngăn xếp lệnh gọi phương thức (đôi khi được gọi là ngăn xếp thực thi chương trình) là cấu trúc dữ liệu hoạt động ngầm để hỗ trợ cơ chế gọi/trả lại phương thức. It also supports the creation, maintenance and destruction of each called method's local variables.

    Tại sao nó được gọi là ngăn xếp cuộc gọi?

    Ngăn xếp cuộc gọi được tổ chức dưới dạng "ngăn xếp", một cấu trúc dữ liệu trong bộ nhớ để lưu trữ các mục theo cách vào trước ra trước, để người gọi chương trình con đẩy địa chỉ trả về vào ngăn xếp và chương trình con được gọi, sau khi kết thúc,

    Con trỏ ngăn xếp cuộc gọi là gì?

    Con trỏ ngăn xếp là một thanh ghi nhỏ lưu trữ địa chỉ bộ nhớ của phần tử dữ liệu cuối cùng được thêm vào ngăn xếp hoặc, trong một số trường hợp, địa chỉ có sẵn đầu tiên trong ngăn xếp.