【发布时间】:2015-07-30 21:20:10
【问题描述】:
par2 有一个小而相当干净的 C++ 代码库,我认为它可以很好地在 GNU/Linux、OS X 和 Windows(使用 MSVC++)上构建。
我想合并一个函数的 x86-64 asm 版本,该函数几乎占用所有 CPU 时间。 (mailing list posts with more details。我的implementation/benchmark here。)
Intrinsics 是显而易见的解决方案,但 gcc 无法生成足够好的代码来从 64 位寄存器一次获取一个字节以用作 LUT 的索引。我也可能会花时间安排指令,以便每个 uop 缓存行包含 4 个 uop 的倍数,因为即使输入/输出缓冲区大小合适,uop 吞吐量也是瓶颈。
我不想在 yasm 上引入构建依赖项,因为很多人安装了 gcc,但没有安装 yasm。
有没有办法在一个单独的文件中用 asm 编写一个函数,供 gcc/clang 和 MSVC 组装? 目标是:
- 没有额外的软件作为构建依赖。 (没有 YASM)。
- 每个 asm 函数只有一个版本。 (不维护相同代码的 MASM 和 AT&T 版本。)
Par2cmdline 的构建系统对于 Unix 是 autoconf/automake,对于 Windows 是 MSVC .sln。
我知道 GNU assemble 有一个 .intel_syntax noprefix 指令,但这只会改变指令格式,不会改变其他汇编程序指令。例如.align 16 与 align 16。我的代码相当简单而且很小,所以如果可以的话,可以使用 C 预处理器 #defines 来解决不同的指令。
我假设在 C++ 中进行 CPU 检测并根据结果设置函数指针应该不是问题,即使我必须为此使用一些 #ifdef 条件编译。
如果没有我所希望的解决方案,我可能会引入一个依赖于 yasm 的构建,并有一个 ./configure --no-asm 选项来禁用在没有 yasm 的 x86 上构建的人的 asm 加速。
处理 Windows 和 Linux ABI 中不同调用约定的首选计划是在我的 C 原型上为我的 asm 函数使用 __attribute__((sysv_abi))。然后我只需要为 SysV ABI 编写函数序言。 MSVC 是否有类似的东西,可以根据某些功能的 SysV ABI 将 args 放入 regs 中? (顺便说一句,这让compiler bug 发痒了,所以如果你想让你的代码与当前的 gcc 一起工作,请小心这个想法。)
【问题讨论】:
-
XY 问题 - gcc 无法生成足够好的代码,无法从 64 位寄存器一次获取一个字节用作 LUT 的索引 你真的应该问这个并提供代码。
-
@Jester:我在我添加的新的最后一段中链接的那个 gcc 错误报告中跑题了。如果你想看看。我真的应该单独报告该性能错误。其实只要编译github.com/pcordes/par2-asm-experiments/blob/master/…
-
我认为这根本不可能。所以我会选择 YASM,人们可以处理它。这不是他们第一次必须安装一些东西来构建一些软件。
-
我认为按照你的建议去做是不切实际的。此外,YASM 可能是第四个最有可能安装在某人机器上的汇编程序。使用 GNU 汇编器(甚至 MASM)会更有意义,因为您会知道至少有一些用户需要安装。最后,不,没有办法告诉 MSVC 使用 System V 调用约定。为什么会有?它不针对任何使用它的系统。使用 Microsoft ABI 会更有意义,因为 GCC 和 clang 确实支持它。
-
@Jester:我不再偷懒,报告gcc问题:gcc.gnu.org/bugzilla/show_bug.cgi?id=67072
标签: visual-c++ gcc assembly x86 sse