模型资源加载引起的内存对齐问题

2 篇文章 0 订阅
2 篇文章 0 订阅

最近需要给远场降噪库编译到android 平台上运行,其中库加载了模型资源文件,考虑到库的通用性,给模型资源文件转成了c的头文件里的数组形式,这样就不需要读取文件了,如下

![(https://img-blog.csdnimg.cn/5803ec967d8b458e8749e66ff804e0fb.png)

编译后在机器上运行64位版本ok,一切正常,但编译32位版本时遇到bus error

在这里插入图片描述

总线错误?没干啥啊,给32位编译FLAGS 同步成64位后无效,Bus error继续。
查了下总的来说android 报bus error 基本是访问了未对齐内存导致,比如
0x0x5594bb4a7f 这个地址%4不等于0,说明地址不是4字节对齐。如果用int * 去取数据就会报错,但
用char* 取数据就ok。为啥64位的正常呢,打印了64位的数据也是不对齐的,为啥64位就ok呢,猜测是64位支持内存不对齐的访问。

用工具排查错误是在下面这行,那看来就是f32有问题了

在这里插入图片描述
看下f32 是个float * 地址,那应该需要4字节对齐
在这里插入图片描述
我们打印下f32的值0x0x5594bb4a7f 果然不是4字节对齐的
怎么办呢,
尝试了下memcpy处理,重新定义一个float 数组,编译器会确保iweightAll 是对齐4字节的,memcpy又可以按字节访问f32

在这里插入图片描述

再来打印iweightAll 果然ok了,但又有其他地方报错了,。。。看来这种方式治标不治本,的确可以解决问题,但需要在所有不对齐的地方使用,同时增加了memcpy的开销

看一下为什么f32是单字节,能否设置4字节对齐

在这里插入图片描述
一顿操作发现,f32是用模型资源取出来的char*赋值的。。。我去,那这肯定很难保证是4字节对齐啊

于是想到新的一招

在这里插入图片描述
重新申请个4的倍数的内存,这样会确保ptr 起始地址是4字节对齐的,给原来的值拷贝进去,ok
搞定了

想想还是有问题啊,这样内存变大了啊
到底是啥原因导致ptr不能4字节对齐呢,能否有办法搞定呢
原先以为是模型解析的时候,模型里的数据类型不确定,可能是void* 也可能是float*等等,导致赋值的时候有问题,可后来想想模型的制定应该没这么蠢吧,so继续追踪下去,打印所有解析的模型资源数据,发现都是4字节倍数,那这很明显了啊,只要模型资源起始地址对齐的,那我们需要解析的数据肯定都是对齐的,打印了下模型资源地址果然是像0x0x5594bb4a7f 这样的,对,就是不对齐,为啥呢,再看下模型资源
在这里插入图片描述
资源的里的数组大小不是4倍数啊。。。打印这个地址果然出来的地址也不是对齐4的(也是有可能对齐的),那对于这种直接定义的数组数据怎么让起始地址对齐呢,想到个简单的解决方法,那就是再扩充几个字节(注意资源长度还是原来的)

在这里插入图片描述
再次打印资源地址,ok了,重新编译代码运行,搞定

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值