【发布时间】:2010-12-26 06:29:48
【问题描述】:
我是使用 SSE/SSE2 指令优化代码的新手,直到现在我还没有走得太远。据我所知,一个常见的 SSE 优化函数如下所示:
void sse_func(const float* const ptr, int len){
if( ptr is aligned )
{
for( ... ){
// unroll loop by 4 or 2 elements
}
for( ....){
// handle the rest
// (non-optimized code)
}
} else {
for( ....){
// regular C code to handle non-aligned memory
}
}
}
但是,我如何正确确定 ptr 指向的内存是否通过例如对齐16 字节?我认为我必须包含非对齐内存的常规 C 代码路径,因为我无法确保传递给此函数的每个内存都将对齐。并且使用内部函数将数据从未对齐的内存加载到 SSE 寄存器似乎非常慢(甚至比常规 C 代码慢)。
提前谢谢你...
【问题讨论】:
-
随机名称,不确定,但我认为像处理最后几个一样单独处理前几个“未对齐”元素可能更有效。然后你仍然可以将 SSE 用于“中间”...
-
嗯,这是一个好点。我会试试看。谢谢!
-
更好:使用标量序言来处理未对齐的元素,直到第一个对齐边界。 (gcc 在使用未知对齐的指针自动矢量化时执行此操作。)或者,如果您的算法是幂等的(如
a[i] = foo(b[i])),则执行潜在未对齐的第一个矢量,然后主循环在第一个对齐边界之后开始向量,然后是在最后一个元素处结束的最终向量。如果数组实际上未对齐和/或计数不是向量宽度的倍数,则其中一些向量将重叠,但仍优于标量。 -
最佳:提供一个提供 16 字节对齐内存的分配器。然后对 16 字节对齐的缓冲区进行操作,而无需修复前导或尾元素。这就是像 Botan 和 Crypto++ 这样的库为使用 SSE、Altivec 和朋友的算法所做的。
标签: c optimization memory sse simd