【发布时间】:2016-10-03 09:45:28
【问题描述】:
使用 MSVC 2013 和 AVX 1,我在一个寄存器中有 8 个浮点数:
__m256 foo = mm256_fmadd_ps(a,b,c);
现在我想为所有 8 个浮点数调用 inline void print(float) {...}。看起来 Intel AVX intrisics 会使这变得相当复杂:
print(_castu32_f32(_mm256_extract_epi32(foo, 0)));
print(_castu32_f32(_mm256_extract_epi32(foo, 1)));
print(_castu32_f32(_mm256_extract_epi32(foo, 2)));
// ...
但是 MSVC 甚至没有这两个内在函数中的任何一个。当然,我可以将值写回内存并从那里加载,但我怀疑在汇编级别没有必要溢出寄存器。
Bonus Q:我当然想写
for(int i = 0; i !=8; ++i)
print(_castu32_f32(_mm256_extract_epi32(foo, i)))
但 MSVC 不理解许多内在函数 需要 循环展开。如何在__m256 foo 中的 8x32 浮点数上编写循环?
【问题讨论】:
-
如果您要打印数据,那么将寄存器溢出到内存几乎无关紧要 - 只需使用合适的联合。
-
@PaulR:简化示例。
-
重要的是
print()是代表一个真正可以完全内联的函数,还是编译器最终必须call一个它看不到代码的函数。到底发生了什么? -
如果你只关心 MSVC,像
foo.m256_f32[i]这样的东西可能会起作用(即foo[i]与 gcc)。 -
@PeterCordes:我有 Paul 想法的递归模板代码。无需展开;只是内联 7 级辅助函数。非常简单——一次调用
print,一次递归调用。对于内联来说应该是微不足道的,这意味着我最终会连续进行 8 次调用,就像展开循环一样。不过还是要检查组装。
标签: c++ visual-c++ avx fma