Alex Shi <seakeel@xxxxxxxxx> 于2021年8月25日周三 下午3:49写道: > > On Wed, Aug 18, 2021 at 4:32 PM Yanteng Si <siyanteng@xxxxxxxxxxx> wrote: > > > > Translate Documentation/core-api/unaligned-memory-access.rst into Chinese. > > > > Signed-off-by: Yanteng Si <siyanteng@xxxxxxxxxxx> > > --- > > .../translations/zh_CN/core-api/index.rst | 2 +- > > .../core-api/unaligned-memory-access.rst | 229 ++++++++++++++++++ > > 2 files changed, 230 insertions(+), 1 deletion(-) > > create mode 100644 Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst > > > > diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst > > index 9367128c4cb7..9bc1dfeab98e 100644 > > --- a/Documentation/translations/zh_CN/core-api/index.rst > > +++ b/Documentation/translations/zh_CN/core-api/index.rst > > @@ -100,10 +100,10 @@ Todolist: > > :maxdepth: 1 > > > > memory-allocation > > + unaligned-memory-access > > > > Todolist: > > > > - unaligned-memory-access > > dma-api > > dma-api-howto > > dma-attributes > > diff --git a/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst b/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst > > new file mode 100644 > > index 000000000000..ab15cc01c922 > > --- /dev/null > > +++ b/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst > > @@ -0,0 +1,229 @@ > > +.. include:: ../disclaimer-zh_CN.rst > > + > > +:Original: Documentation/core-api/unaligned-memory-access.rst > > + > > +:翻译: > > + > > + 司延腾 Yanteng Si <siyanteng@xxxxxxxxxxx> > > + > > +:校译: > > + > > + 时奎亮<alexs@xxxxxxxxxx> > > Do I did sth on this series? :) Yeah, thank you for your review!>_< > > > + > > +.. _cn_core-api_unaligned-memory-access: > > + > > +============== > > +非对齐内存访问 > > +============== > > + > > +:作者: Daniel Drake <dsd@xxxxxxxxxx>, > > +:作者: Johannes Berg <johannes@xxxxxxxxxxxxxxxx> > > + > > +:感谢他们的帮助: Alan Cox, Avuton Olrich, Heikki Orsila, Jan Engelhardt, > > + Kyle McMartin, Kyle Moffett, Randy Dunlap, Robert Hancock, Uli Kunitz, > > + Vadim Lobanov > > + > > + > > +Linux运行在各种各样的架构上,这些架构在内存访问方面有不同的表现。本文介绍了一些 > > +关于不对齐访问的细节,为什么你需要编写不引起不对齐访问的代码,以及如何编写这样的 > > +代码 > > + > > + > > +非对齐访问的定义 > > +================ > > + > > +当你试图从一个不被N偶数整除的地址(即addr % N != 0)开始读取N字节的数据时,就 > > +会发生无对齐内存访问。例如,从地址0x10004读取4个字节的数据是可以的,但从地址 > > +0x10005读取4个字节的数据将是一个不对齐的内存访问。 > > + > > +上述内容可能看起来有点模糊,因为内存访问可以以不同的方式发生。这里的背景是在机器 > > +码层面上:某些指令在内存中读取或写入一些字节(例如x86汇编中的movb、movw、movl)。 > > +正如将变得清晰的那样,相对容易发现那些将编译为多字节内存访问指令的C语句,即在处理 > > +u16、u32和u64等类型时。 > > + > > + > > +自然对齐 > > +======== > > + > > +上面提到的规则构成了我们所说的自然对齐。当访问N个字节的内存时,基础内存地址必须被 > > +N平均分割,即addr % N == 0。 > > + > > +在编写代码时,假设目标架构有自然对齐的要求。 > > + > > +在现实中,只有少数架构在所有大小的内存访问上都要求自然对齐。然而,我们必须考虑所 > > +有支持的架构;编写满足自然对齐要求的代码是实现完全可移植性的最简单方法。 > > + > > + > > +为什么非对齐访问时坏事 > > +====================== > > + > > +执行非对齐内存访问的效果因架构不同而不同。在这里写一整篇关于这些差异的文档是很容 > > +易的;下面是对常见情况的总结: > > + > > + - 一些架构能够透明地执行非对齐内存访问,但通常会有很大的性能代价。 > > + - 当不对齐的访问发生时,一些架构会引发处理器异常。异常处理程序能够纠正不对齐的 > > + 访问,但要付出很大的性能代价。 > > + - 一些架构在发生不对齐访问时,会引发处理器异常,但异常中并没有包含足够的信息来 > > + 纠正不对齐访问。 > > + - 有些架构不能进行无对齐内存访问,但会默默地执行与请求不同的内存访问,从而导致 > > + 难以发现的微妙的代码错误! > > + > > +从上文可以看出,如果你的代码导致不对齐的内存访问发生,那么你的代码在某些平台上将无 > > +法正常工作,在其他平台上将导致性能问题。 > > + > > +不会导致非对齐访问的代码 > > +======================== > > + > > +起初,上面的概念似乎有点难以与实际编码实践联系起来。毕竟,你对某些变量的内存地址没 > > +有很大的控制权,等等。 > > + > > +幸运的是事情并不复杂,因为在大多数情况下,编译器会确保事情为你工作。例如,以下面的 > > 编译器会确保代码工作正常。 ok! > > > +结构体为例:: > > + > > + struct foo { > > + u16 field1; > > + u32 field2; > > + u8 field3; > > + }; > > + > > +让我们假设上述结构体的一个实例驻留在从地址0x10000开始的内存中。根据基本的理解,访问 > > +field2会导致非对齐访问,这并不是不合理的。你会期望field2位于该结构体的2个字节的偏移 > > +量,即地址0x10002,但该地址不能被4平均整除(注意,我们在这里读一个4字节的值)。 > > + > > +幸运的是,编译器理解对齐约束,所以在上述情况下,它会在field1和field2之间插入2个字节 > > +的填充。因此,对于标准的结构体类型,你总是可以依靠编译器来填充结构体,以便对字段的访 > > +问可以适当地对齐(假设你没有将字段定义不同长度的类型)。 > > + > > +同样,你也可以依靠编译器根据变量类型的大小,将变量和函数参数对齐到一个自然对齐的方案。 > > + > > +在这一点上,应该很清楚,访问单个字节(u8或char)永远不会导致无对齐访问,因为所有的内 > > +存地址都可以被1均匀地整除。 > > + > > +在一个相关的话题上,考虑到上述因素,你可以观察到,你可以对结构体中的字段进行重新排序, > > +以便将字段放在不重排就会插入填充物的地方,从而减少结构体实例的整体常驻内存大小。上述 > > +例子的最佳布局是:: > > + > > + struct foo { > > + u32 field2; > > + u16 field1; > > + u8 field3; > > + }; > > + > > +对于一个自然对齐方案,编译器只需要在结构的末尾添加一个字节的填充。添加这种填充是为了满 > > +足这些结构的数组的对齐约束。 > > + > > +另一点值得一提的是在结构体类型上使用__attribute__((packed))。这个GCC特有的属性告诉编 > > +译器永远不要在结构体中插入任何填充,当你想用C结构体来表示一些“off the wire”的固定排列 > > +的数据时,这个属性很有用。 > > + > > +你可能会倾向于认为,在访问不满足架构对齐要求的字段时,使用这个属性很容易导致不对齐的访 > > +问。然而,编译器也意识到了对齐的限制,并且会产生额外的指令来执行内存访问,以避免造成不 > > +对齐的访问。当然,与非打包的情况相比,额外的指令显然会造成性能上的损失,所以打包属性应 > > since 'packed' is a attribute of compiler, we'd better keep it in English? ok! > > As to others, Reviewed-by: Alex Shi <alexs@xxxxxxxxxx> > Thanks, Yanteng