【发布时间】:2011-02-27 20:34:31
【问题描述】:
我试图弄清楚如何最好地预先计算一些正弦和余弦值,将它们存储在对齐的块中,然后将它们用于 SSE 计算:
在我的程序开始时,我创建了一个包含成员的对象:
static __m128 *m_sincos;
然后我在构造函数中初始化该成员:
m_sincos = (__m128*) _aligned_malloc(Bins*sizeof(__m128), 16);
for (int t=0; t<Bins; t++)
m_sincos[t] = _mm_set_ps(cos(t), sin(t), sin(t), cos(t));
我在使用m_sincos的时候遇到了三个问题:
- 数据似乎没有对齐
movaps xmm0, m_sincos[t] //crashes
movups xmm0, m_sincos[t] //does not crash
-变量似乎不正确
movaps result, xmm0 // returns values that are not what is in m_sincos[t]
//Although, putting a watch on m_sincos[t] displays the correct values
-真正让我感到困惑的是,这使一切正常(但太慢了):
__m128 _sincos = m_sincos[t];
movaps xmm0, _sincos
movaps result, xmm0
【问题讨论】:
-
我刚刚做了一个 sizeof(__m128)、sizeof(m_sincos[t]) 和 sizeof(result),它们都返回“16”
-
使用_mm_malloc而不是_aligned_malloc似乎功能完全一样,而且就内存位置而言,当我初始化m_sincos时,地址是:0x260e2720,然后当我去使用它时,地址是仍然是 0x260e2720... 这有帮助吗?
-
hmm,尝试在每次加载之前放置 assert 语句以检查对齐而不是组装,您可以尝试 _mm_load_ps 内在函数吗?
-
@aaa - 使用 _mm_store_ps(result,m_sincos[t]);这工作正常,并返回适当的值!至于检查对齐的断言语句,你只是想让我检查 sizeof(m_sincos[t]) 吗?因为我正在这样做并且它们总是大小为 16,但我真的很好奇为什么我不能使用汇编代码,内在和汇编之间的区别是什么?
-
这种重复似乎是个糟糕的主意,除非您的表非常小,或者您反复使用内存中的相同
__m128。执行[c, s]的 8B 负载并将其随机播放以获取[c, s, s, c]非常便宜,并且可能会通过减少缓存未命中来收回成本。与让编译器进行索引相比,内联 asm 只是 bad (因此它可以在循环中将某些内容增加 16)。如果您使用 asm,请在 asm 中编写循环或函数,而不是片段。
标签: c++ alignment intrinsics