_mm_store_si128 上的 SSE 段错误

Posted

技术标签:

【中文标题】_mm_store_si128 上的 SSE 段错误【英文标题】:SSE segfault on _mm_store_si128 【发布时间】:2017-04-04 10:32:15 【问题描述】:

当我尝试加载一些使用内在函数生成的密文时,我遇到了段错误。我根本不明白这个错误。代码示例:

unsigned char c[177]; 
unsigned char m[161];
auth = _mm_setzero_si128();
unsigned char M_star[BLOCKSIZE];
__m128i tag = auth; 
for(i=0;i<numblocks_mes;++i)

    M = _mm_load_si128(m+i*BLOCKSIZE);
    idx = _mm_set_epi64x(zero,i); // both inputs are unsigned long long
    tmp = encrypt_block(M,idx);
    tag = _mm_xor_si128(tag,tmp);

if(fin_mes) 

    memcpy(M_star,m+numblocks_mes*BLOCKSIZE,fin_mes);
    A_star[fin_mes] = 0x80;
    memset(M_star+fin_mes+1,0,BLOCKSIZE-(fin_mes+1));
    M = _mm_load_si128(M_star);
    idx = _mm_set_epi64x(tag_fin,numblocks_mes); // both inputs are unsigned long long
    tmp = encrypt_block(M,idx); // Contains calls to AES
    tag = _mm_xor_si128(tag,tmp);

// print128_asint(tag);
tag = encrypt_block(tag,nonce);
// Following line causes segfault
_mm_store_si128( (__m128i *)&c[numblocks_mes*BLOCKSIZE+fin_mes], tag ); // numblocks_mes*BLOCKSIZE+fin_mes = 161

我之前尝试过查看其他类似的问题,并尝试了它们,但我没有找到任何适合我的东西。

【问题讨论】:

我忘了写fin_mes是一个整数,也就是1,BLOCKSIZE是16,numblocks_mes是10。 会不会是对齐问题? 【参考方案1】:

目标地址需要 16 字节对齐。由于c[] 本身没有特定的对齐方式,因此也不能保证c 内任意偏移的地址(即使这些偏移是 16 的倍数)。

解决方案:使用_mm_storeu_si128 而不是_mm_store_si128


请注意,您似乎也很幸运地收到了来自mMstar 的负载——您几乎可以肯定地将它们更改为使用_mm_loadu_si128

【讨论】:

非常感谢,它运行良好。看起来我还有更多的代码需要检查和修复,因为我不应该依赖运气来让我的代码工作。 嗯,是的,有两种可能的方法:(a) 确保所有数据都是 16 字节对齐的(可能并不总是可能的)或 (b) 不对数据对齐做任何假设并使用未对齐的负载/商店。在较旧的架构上,使用未对齐的加载/存储可能会导致严重的性能损失,但在最近/当前的架构上通常可以忽略不计。

以上是关于_mm_store_si128 上的 SSE 段错误的主要内容,如果未能解决你的问题,请参考以下文章

SSE2:如何将 _m128 简化为一个单词

SSE:如何将 _m128i._i32[4] 减少到 _m128i._i8

__m128, SSE4 中最大绝对值的符号

尝试在 SSE 编程中使用和掩码添加 __m128

SSE:将 __m128 转换为浮点数

在 sse 向量 m128 中找到最大浮点数