yuv数据提取请详细请查看我的这篇博客([Ubuntu]Scrcpy+Zeromq实现手机屏幕yuv数据传输,并通过OpenCV实现连续播放——(一)(图文+代码解析)_又是谁在卷的博客-CSDN博客)。在进行yuv数据提取时,如果直接使用手机分辨率的高(height)和宽(width)为依据进行提取会发现图片是扭曲的。这就涉及到本文所讲到的内存对齐的问题了。
那我们的内心就会出现灵魂三问了。
什么是内存对齐?
如何进行内存对齐?
内存对齐对我们有什么好处?
我们来通过一个简答的例子理解解决以上三个问题
假设我们要读取一个int类型数据(长度为4个字节,如下图所示)。如果我们没有进行内存对齐,数据在内存中可以随意存储的话,将会出现以下情况。int如果存放在位置为内存为1-5的位置上,cpu读取时每4个单位读取一次(32位系统的情况,64位为8位)。那么我们想要获取int数据就需要读取两次,并且第一次需要剔除0,第二次需要剔除5,6,7。这样处理数据的效率就会极其低下。所以我们选择使用内存对齐的方式,将int类型存放在4的倍数的内存地址中。
其实内存对齐的方法运用十分广泛,在进行结构体的创建时,如果注意到内存对齐的问题,我们将提高内存的利用率。避免浪费不必要的内存损失。下面我将深入的介绍一下关于结构体的内存对齐的知识。
我们来看以下两个结构体。第一个结构体中char a和char b都只占一个字节,比我们的读取步长4要小,所以我们可以将它们相邻的存储在一起,占位为0~1。但是下一个数据类型是int,占4个字节,那么就存放到4~8的位置,那么结构体大小为8个字节。但是我们观察strucr M2,char a占一个字节,占0的位置。那么我们下一个int就只能存储在4~7的位置上(因为1~3的位置不够),char b就存储在8的位置上。为了下一个数据的对齐,那么struct的大小为12(注意我们是从0开始算起的,0~11有12个数。因为8~11剩余大小为3,除非下一个数据类型大小为1,否则再次进行内存对齐时必然会跳过这段内存将数据写在12的位置上)。
两者对比我们会发现,如果根据数据类型合理的安排结构体中数据的存储位置,还能起到节省内存的效果。
//结构体1
struct M1
{
char a;
char b;
int c;
};
//结构体2
struct M2
{
char a;
int c;
char b;
};
1. 所以内存对齐就是为了方便计算机读取内存数据的一种存储机制。
2.内存读取的方式因编译器的不同而不同,有的默认4个字节,有的默认8个字节
我们还可以通过以下代码修改内存对齐数
pragma pack(内存对齐数)
3.内存对齐能提升计算机处理数据的速度,同时在结构体中根据数据类型合理安排存储数据的顺序还可以节省内存
希望通过一个简单的例子可以让大家明白内存对齐的知识,如果有帮助,期待你的一键三连哈~