【问题标题】:Using STL containers in GNU Assembler在 GNU 汇编器中使用 STL 容器
【发布时间】:2011-06-20 14:26:59
【问题描述】:

是否可以将 STL“链接”到汇编程序,例如类似于链接 glibc 以使用 strlen 等函数?具体来说,我想编写一个汇编函数,它将 std::vector 作为参数,并将成为 lib 的一部分。如果可以,是否有相关文档?

【问题讨论】:

  • 函数中需要填充向量吗?如果只是将数据传递给它,您可以编写函数来接受普通数组并将&vec.front() 作为参数传递。
  • 用 C 链接做一些事情是我的计划 A。

标签: stl assembly


【解决方案1】:

任何 C++ 模板的使用都需要编译器生成这些模板的实例化。因此,您并没有真正将诸如 STL 之类的东西“链接”到程序中;编译器会根据您在库中使用的模板生成目标代码。

但是,如果您可以编写一些 C++ 代码强制为您需要使用的任何类型和其他参数实例化模板,然后编写一些 C 链接函数来包装这些模板实例化的使用,那么您应该能够从您的汇编代码中调用它们。

【讨论】:

  • 该代码将是,例如:template std::vector<int>; 在一个 UT (cpp) 中。然后使用 objdump -t 或 nm 或类似方法来获取损坏的名称。受虐狂的食物:)
  • 听起来不错,感谢您的解释和对 objdump 的引用。 :)
  • 如果是我,我不会使用那些乱七八糟的名字。我会围绕我需要使用的每个操作编写一些小的 C 包装函数。
  • Kristopher:我想知道这是否值得麻烦,因为无论如何这些函数可能都依赖于编译器(也可能是-version)。此类预防措施仅适用于具有标准化未损坏签名的函数。
  • 我认为,从长远来看,extern "C" addObjectToList(void *list, void *object); 会比使用混乱的名称更容易维护。
【解决方案2】:

我坚信你做错了。使用汇编器不会加快您处理数据的速度。如果您必须使用现有的汇编代码,只需传递原始缓冲区

std::vector 根据定义(在标准中)与原始缓冲区(数组)兼容;该标准要求连续分配。只有重新分配才能使包含元素数据的内存区域失效。简而言之,如果 C++ 代码可以知道所需的(最大)容量和适当的reserve()/resize(),则可以将&vector[0] 作为缓冲区地址传递,并且非常高兴。

如果汇编代码需要决定重新分配多少(多少),让它使用 malloc。完成后,您应该可以将该数组用作 STL 容器:

std::accumulate(buf, buf+n, 0, &dosomething);

或者,您可以使用 std::tr1::array<T, n>boost::array<T, n> 是 POD 的事实,并使用在库中分配的缓冲区 on 放置新的位置(请参阅此处:placement new + array +alignment 或 @987654322 @)


旁注

我怀疑您出于错误的原因使用了汇编。优化编译器将充分利用现代处理器(包括 SSE1-4 等 SIMD)的全部潜力;

例如对于 gcc 看看

  • __attibute__(例如指针限制 例如对齐和别名保证:这将为编译器启用更强大的矢量化选项);
  • -ftree_vectorize-ftree_vectorizer_verbose=2, -march=native

还要注意,由于编译器无法确定是什么注册了外部(甚至内联)汇编过程破坏,它必须假定所有寄存器都被破坏,从而导致潜在的性能下降。请参阅 http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html 了解使用内联汇编的方法以及对 gcc 的适当提示。

可能完全跑题了:-fopenmpgnu::parallel

奖励:以下关于汇编和 c++ 中(过早)优化的参考资料可能会派上用场:

还有其他一些relevant resources

【讨论】:

  • 非常感谢您的提示和参考!这绝对是有趣和有帮助的。不过,我应该提一下,目的不是加快程序的运行时性能,而是加快编译时间。
  • 那么一定要s/assembly/ANSI C/g 并有一个更轻松的时间(阅读其余部分不变)
猜你喜欢
  • 1970-01-01
  • 2016-11-15
  • 2021-03-04
  • 2011-07-11
  • 1970-01-01
  • 2017-01-07
  • 2014-06-19
  • 1970-01-01
  • 2020-09-20
相关资源
最近更新 更多