我在最里面的循环中有一些代码,我用它来钳制我正在编写的光栅化算法的一些错误值:
float cerror[4] = {
MINF(error[0], 1.0f),
MINF(error[1], 1.0f),
MINF(error[2], 1.0f),
MINF(error[3], 1.0f)
};
其中MINF只是MINF(a,b)=((a)<(b))?(a) : (b)
事实证明,我必须在这个内部循环中更新 4 个错误值,所有浮点数,所以如果我可以将它们全部存储在 SSE 寄存器中并使用 minps 而不是单独计算最小值,那就太好了,但是编译器似乎没有为我这样做。
我什至尝试将它移到它自己的函数中,这样我就可以看到矢量化器的输出:
void fclamp4(float* __restrict__ aa, float* __restrict__ bb) {
for (size_t ii=0; ii < 4; ii++) {
aa[ii] = (bb[ii] > 1.0) ? 1.0f : bb[ii];
}
}
这给了我类似的东西:
inc/simplex.h:1508:注意:未矢量化:不支持的数据类型 bool
inc/simplex.h:1507:注意:函数中的矢量化 0 循环。
有没有办法更好地鼓励编译器为我这样做?如果我可以避免它,我宁愿不直接跳到内在,这样代码就可以保持可移植性。是否有通用模式的一般参考?
最后,我所有的错误/错误/错误增量都存储在堆栈上的 float[4] 数组中,我需要手动对齐它们还是编译器可以为我处理?
编辑:玩一个对齐的类型,仍然没有骰子。
#include <stdio.h>
#include <stdlib.h>
typedef float __attribute__((aligned (16))) float4[4];
inline void doit(const float4 a, const float4 b, float4 c) {
for (size_t ii=0; ii < 4; ii++) {
c[ii] = (a[ii] < b[ii]) ? a[ii] : b[ii];
}
}
int main() {
float4 a = {rand(), rand(), rand(), rand() };
float4 b = {1.0f, 1.0f, 1.0f, 1.0f };
float4 c;
doit((float*)&a, (float*)&b, (float*)&c);
printf("%f\n", c[0]);
}
矢量化器说:
ssetest.c:7:注意:vect_model_load_cost:对齐。
ssetest.c:7:注意:vect_model_load_cost:inside_cost = 4,outside_cost = 0。
ssetest.c:7:注意:vect_model_load_cost:对齐。
ssetest.c:7:注意:vect_model_load_cost:inside_cost = 4,outside_cost = 0。
ssetest.c:7:注意:未矢量化:不支持相关 stmt:D.3177D.3177_22 = iftmp.4_18 < iftmp.4_21;ssetest.c:12:注意:函数中的向量化 0 循环。
再次编辑:我应该注意我一直在 GCC 4.4.7 (RHEL 6) 和 GCC 4.6 (Ubuntu) 上尝试这个,但都没有运气。