7

_Unwind_SjLj_Unregister 和 _Unwind_SjLj_Register 是什么?在我的 gprof 报告中,我将他们列为我的顶级处理器时间用户。谷歌只返回链接给抱怨这两个错误的人。

这是我报告中唯一有时间的部分!= 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)

我正在运行 Windows 7 x64,并使用代码块 10.05 gcc 进行编译

编辑:

在启用强制程序运行 64 秒的功能后,它现在看起来像:

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
4

5 回答 5

4

我相信这是异常处理。当人们试图链接到在不同编译器中构建的 C++ 库时,问题大多会出现。

于 2011-06-29T05:18:19.463 回答
3

我不能在这里给出最好的答案,但我知道 SjLj 指的是 setjmp 和 longjmp。这些通常用于异常处理。我认为_Unwind_SjLj_Register当你输入一条try语句(“注册”一个 SjLj 异常处理程序)时,编译器将在内部使用它,并_Unwind_SjLj_Unregister在你退出try语句时使用它。不过有点猜测。

于 2011-06-29T05:20:12.287 回答
1

第一:对于像这样的问题,可能值得一提你的编译器和平台。

现在:在某些平台/某些配置/某些编译器上,C++ 中的异常处理是使用“setjmp”和“longjmp”函数(标准 C 库的一部分)实现的。_Unwind_SjLj_[Un]register 方法与此有关。粗略地说,当进入 try..catch 块时,需要注册处理程序,离开块时,需要注销处理程序。

于 2011-06-29T05:20:08.407 回答
0

这是一个非常特殊的情况,但我在 R 中使用 Rcpp 包时遇到了这个错误。结果是 -std=c++11 标志导致了这个问题,并且使用 -std=c++0x 一切正常。

于 2016-05-14T00:18:26.397 回答
-1

根据我在 Windows 上使用 gcc 的经验,您可以通过避免内存分配或在内部循环中分配内存的可能性来避免大量此类开销。其他答案指出,当可能引发异常并导致调用析构函数时,您会收到这些调用。在我的程序中,大多数地方可能引发的异常是 std::bad_alloc ,当内存分配失败时会出现这种异常。

因此,如果您的程序中的潜在异常也主要是 std::bad_alloc,并且您可以将分配或分配的可能性移出内部循环,那么 GCC 将不必处理潜在 std:: 之后的清理工作内部循环中的 bad_alloc 异常。那应该加快速度。记住要考虑像 vector::push_back 这样的东西可以分配内存。即使您首先调用 vector::reserve 以排除重新分配,GCC 也可能不够聪明,无法意识到重新分配不会发生。

我不知道您使用的是什么版本的 GCC,但我相信最新版本的 GCC 使用了没有这种开销的异常处理机制。不过,我可能是错的。当然可以实现不需要动态注册析构函数的异常处理机制,因为可以从程序计数器中推断出需要调用的析构函数。

于 2011-06-30T19:44:06.717 回答