使用SSE intrinsics时出现double free或内存损坏错误如何解决?
错误原因分析
- 核心问题是数组越界访问:你定义的测试用例
N1=1001不是8的倍数,add_prod函数的循环逻辑每次处理8个short元素,当i走到1000的时候,i < 1001条件成立进入循环,此时对src+i、dst+i执行128位(对应8个short)的读写操作,会访问到数组下标1000~1007的位置,而你申请的数组长度只有1001,下标最大是1000,越界的写操作破坏了堆内存的元数据结构,所以后续执行free的时候就会报内存 corruption 错误。 - valgrind报的
Invalid write of size 8也对应这个问题:128位写入操作的后半部分落到了非法内存区域。
修复方案
你可以对add_prod函数做修改,把不足8个的剩余元素用标量逻辑处理,示例修改后的代码如下:
static void add_prod(const short* src, short* dst, short x, int n) { __m128i _src, _dst, _scalar = _mm_set_epi16(x,x,x,x,x,x,x,x); int i = 0; // 先处理满8个的部分 for(; i <= n - 8; i += 8) { _src = _mm_loadu_si128((const __m128i*) (src+i)); _dst = _mm_loadu_si128((const __m128i*) (dst+i)); _src = _mm_mullo_epi16(_src, _scalar); _dst = _mm_add_epi16(_src, _dst); _mm_storeu_si128((__m128i*) (dst+i), _dst); } // 处理剩余不足8个的元素 for(; i < n; i++) { dst[i] += src[i] * x; } }
内容的提问来源于stack exchange,提问作者Naruto Uzumaki
相关产品推荐
相关产品推荐

