2011-06-29 24 views
5

_Unwind_SjLj_Unregister và _Unwind_SjLj_Register là gì? Tôi lấy chúng làm người dùng thời gian xử lý hàng đầu trong báo cáo gprof của tôi. google chỉ trả về các liên kết tới những người phàn nàn về các lỗi với hai lỗi này._Unwind_SjLj_Unregister và _Unwind_SjLj_Register là gì?

heres phần duy nhất của báo cáo của tôi có lần = 0:

Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls ms/call ms/call name  
33.33  0.03  0.03        _Unwind_SjLj_Unregister 
22.22  0.05  0.02        _Unwind_SjLj_Register 
11.11  0.06  0.01 13886  0.00  0.00 toint(std::string, int) 
11.11  0.07  0.01  4380  0.00  0.00 hexlify(std::string) 
11.11  0.08  0.01  2994  0.00  0.00 std::_Deque_iterator<unsigned char, unsigned char const&, unsigned char const*>::operator+(int) const 
11.11  0.09  0.01        std::string::assign(char const*, unsigned int) 

im chạy windows 7 x64, và biên soạn với CodeBlocks 10.05 gcc

chỉnh sửa:

sau cho phép các chức năng buộc chương trình chạy 64 giây, bây giờ trông giống như:

Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls s/call s/call name  
    8.45  3.49  3.49        _Unwind_SjLj_Register 
    7.36  6.53  3.04 4000006  0.00  0.00 CAST128::setkey(std::string) 
    5.86  8.95  2.42        _Unwind_SjLj_Unregister 
    4.36  10.75  1.80 64000080  0.00  0.00 CAST128::F(int&, unsigned int&, unsigned int&, unsigned char&) 
    3.68  12.27  1.52        __dynamic_cast 
    3.37  13.66  1.39        std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) 
    3.25  15.00  1.34        std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() 
    2.88  16.19  1.19        std::istreambuf_iterator<char, std::char_traits<char> > std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_int<unsigned long long>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, unsigned long long&) const 

Trả lời

4

Tôi tin rằng đó là xử lý ngoại lệ. Các vấn đề chủ yếu xuất hiện khi mọi người cố gắng liên kết với một thư viện C++ được xây dựng trong một trình biên dịch khác.

+0

là một điều tốt hay một điều xấu mà điều này là trên đầu trang? Tôi không gặp bất kỳ vấn đề gì (tôi nghĩ). chỉ có trong báo cáo – calccrypto

+2

Hmm. Đó là một chút ngạc nhiên khi chương trình của bạn đang sử dụng 55% thời gian của nó trên các trình xử lý ngoại lệ. Nhưng hãy suy nghĩ một chút hợp lý hơn: Tôi lưu ý rằng hồ sơ của bạn đã đo chính xác 0,03 giây và 0,02 giây cho những người đó. Và 0,01 giây cho mọi thứ khác. Dường như chương trình hầu như không mất thời gian để chạy, và trình lược tả không thể đo lường bất kỳ điều gì trong độ chi tiết nhỏ hơn 0,01 giây. Bạn cần chạy lâu hơn để có được bất kỳ thông tin có ý nghĩa nào. Về cơ bản bạn đang nhìn vào sáu hạt cát, lớn hơn một chút so với những hạt khác, và cố gắng tìm ra cách để làm sạch bãi biển. – mgiuca

+0

lol. chương trình của tôi mất khoảng 2 giây để chạy. có thể giải thích nó – calccrypto

1

Đầu tiên: có thể đáng nói đến trình biên dịch và nền tảng của bạn cho các câu hỏi như thế này.

Bây giờ: Trên một số nền tảng/một số cấu hình/một số trình biên dịch, xử lý ngoại lệ trong C++ được thực hiện bằng các hàm "setjmp" và "longjmp" (một phần của thư viện C chuẩn). Các phương thức đăng ký _Unwind_SjLj_ [Un] là để làm điều này. Nói thật, khi một khối try..catch được nhập vào, một trình xử lý cần phải được đăng ký và khi khối còn lại, trình xử lý cần phải được hủy đăng ký.

3

Tôi không thể đưa ra câu trả lời đúng nhất ở đây, nhưng tôi biết rằng SjLj đề cập đến setjmp và longjmp. Chúng thường được sử dụng để xử lý ngoại lệ. Tôi nghĩ rằng _Unwind_SjLj_Register sẽ được trình biên dịch sử dụng nội bộ khi bạn nhập câu lệnh try (để "đăng ký" một trình xử lý ngoại lệ SjLj) và _Unwind_SjLj_Unregister sẽ được sử dụng khi bạn thoát khỏi tuyên bố try. Phân loại của đoán mặc dù.

+0

tôi không tin rằng tôi có bất kỳ 'try's trong chương trình của tôi. ** EDIT ** nope. Tôi đã kiểm tra. nó có thể được ẩn trong một số thư viện STL – calccrypto

+0

Có thể có các trys trong một số thư viện mà bạn đang gọi. – mgiuca

+0

Nhưng bạn đang sử dụng thư viện chuẩn C++, và nó có 'try'. – davmac

0

Trong kinh nghiệm sử dụng gcc trên Windows, bạn có thể tránh được rất nhiều chi phí này bằng cách tránh cấp phát bộ nhớ hoặc khả năng phân bổ bộ nhớ trong vòng lặp bên trong của bạn. Các câu trả lời khác chỉ ra rằng bạn nhận được các cuộc gọi này khi một ngoại lệ có thể được ném và gây ra các cuộc gọi đến destructors. Trong các chương trình của tôi, ngoại lệ có thể được ném vào hầu hết các nơi là std :: bad_alloc mà bạn nhận được khi cấp phát bộ nhớ không thành công. Vì vậy, nếu các ngoại lệ tiềm năng trong chương trình của bạn cũng chủ yếu là std :: bad_alloc, và bạn có thể di chuyển phân bổ hoặc tiềm năng phân bổ ra khỏi vòng lặp bên trong của bạn, thì GCC sẽ không phải xử lý sau khi dọn dẹp std tiềm năng :: bad_alloc ngoại lệ bên trong vòng lặp bên trong của bạn. Điều đó sẽ tăng tốc mọi thứ. Hãy nhớ xem xét những thứ như vector :: push_back có thể cấp phát bộ nhớ. Ngay cả khi bạn gọi vector :: dự trữ đầu tiên để loại trừ các phân bổ lại, GCC có thể không đủ thông minh để nhận ra rằng sự sắp xếp lại sẽ không xảy ra.

Tôi không biết bạn đang sử dụng phiên bản GCC nào, nhưng tôi tin rằng phiên bản mới nhất của GCC sử dụng cơ chế xử lý ngoại lệ không có phí này. Tôi có thể sai về điều đó, mặc dù. Nó chắc chắn có thể thực hiện một cơ chế xử lý ngoại lệ mà không yêu cầu đăng ký destructors động vì các destructors cần được gọi có thể được suy ra từ bộ đếm chương trình.

0

Đây là trường hợp khá cụ thể, nhưng tôi đã gặp lỗi này khi sử dụng gói Rcpp trong R. Tắt cờ -std = C++ 11 gây ra sự cố và mọi thứ hoạt động tốt với -std = C++ 0x.