_mm256_loadu_ps转换__m256有数量上限?两段AVX代码为何一正常一崩溃?
AVX指令集代码段错误的原因分析与修复方案
问题描述
使用AVX指令集时遇到两种情况:
- 第一段代码运行正常,可正常访问值;
- 第二段代码运行失败,访问值时触发段错误。
两段代码如下:
__m256 bli[512]; for(size_t i =0; i < oc; i++){ float ua_f[8]; for(size_t j=0;j<8;j++){ ua_f[j] = bias[i*8 + j]; } bli[i] = _mm256_loadu_ps(ua_f); } __m256 mli[2100000]; for(size_t m=0; m < output_dim; m++){ for(size_t n = 0; n<ic; n++){ float ua_f[8]; for(size_t i=0; i<8; i++){ ua_f[i] = matrix[(i + 8*n)*output_dim + m]; } size_t cal = m*ic +n; mli[cal] = _mm256_loadu_ps(ua_f); } }
核心差异分析
两段代码的关键差异在于数组的内存分配位置与大小:
bli[512]是栈上分配的数组,每个__m256占32字节,总大小为512*32=16KB,远小于系统默认栈空间(通常Linux为8MB,Windows为1MB),因此能正常运行。mli[2100000]同样是栈上分配,总大小为2100000*32≈64MB,远超栈空间上限,直接触发栈溢出,导致段错误。
修复方案
要让第二段代码正常运行,需要把mli的内存分配从栈转移到不受大小限制的堆或静态存储区:
方案1:使用堆分配(推荐)
用new或malloc在堆上分配内存,用完记得释放:
// C++风格堆分配 __m256* mli = new __m256[2100000]; // 原代码逻辑... // 用完释放内存 delete[] mli;
或者用C风格的malloc:
__m256* mli = (__m256*)malloc(2100000 * sizeof(__m256)); if (!mli) { // 处理内存分配失败的情况 } // 原代码逻辑... free(mli);
方案2:声明为全局变量
全局变量存储在静态存储区,不受栈大小限制:
// 放在函数外部声明 __m256 mli[2100000]; int main() { // 原代码逻辑... }
内容的提问来源于stack exchange,提问作者cueqlp
相关产品推荐
相关产品推荐

