如何理解的仿生bcopy.c这code段? [英] How to understand this code snippet in the bcopy.c of bionic?
问题描述
我看了在的http:// androidxref .COM / 4.0.4 /外部参照/仿生/的libc /串/ bcopy.c
发现以下code是很难理解的,任何人可以解释一下吗?
I read the memcpy implementation in the http://androidxref.com/4.0.4/xref/bionic/libc/string/bcopy.c find following code is hard to understand, can anybody explain it?
36 /*
37 * sizeof(word) MUST BE A POWER OF TWO
38 * SO THAT wmask BELOW IS ALL ONES
39 */
40 typedef long word; /* "word" used for optimal copy speed */
41
42 #define wsize sizeof(word)
43 #define wmask (wsize - 1)
44
...
/*
78 * Copy forward.
79 */
80 t = (long)src; /* only need low bits */
81 if ((t | (long)dst) & wmask) {
82 /*
83 * Try to align operands. This cannot be done
84 * unless the low bits match.
85 */
86 if ((t ^ (long)dst) & wmask || length < wsize)
87 t = length;
88 else
89 t = wsize - (t & wmask);
是什么意思,这些位操作的?他们的意图是什么?
What is mean of these bitwise operations? What is their intent?
推荐答案
其基本思路是,以满足对齐约束:每个单词,一次要复制一个字必须在一个字边界对齐
The basic idea is to meet alignment constraints: each "word" to be copied one word at a time must be aligned on a "word" boundary.
某些CPU有此作为一项基本约束条件,即加载和存储必须在自然的边界发生。在旧的ARM处理器中的地址的低位被完全忽略,这样从一个奇怪的值地址的负载或两个字节存储有同样的效果:
Some CPUs have this as a fundamental constraint, that loads and stores must occur on a "natural" boundary. On older ARM processors the low bits of the address are actually ignored entirely, so that a load or store of two bytes from an odd-valued address have the same effect as:
short w = *(short *)(addr & ~1);
有关实例。在一些其他CPU未对齐加载或存储的结果陷阱(MIPS和SPARC例如),还有人会做它,但性能上的损失(86)。
for instance. On some other CPUs an unaligned load or store results in a trap (MIPS and SPARC for instance), and still others will just do it, but with a performance penalty (x86).
因此,假设你是从地址0x12345复制大量的字节数(比如说,他们的4096),以解决0x22345,那字大小为4个字节。如果我们先复制三个字节,地址现在将0x12348和0x22348。在这一点上,我们可以只复制1023 4字节字,一次一个字,没有绊倒在任何对齐问题。之后,我们将有一个剩余字节复制,因为4096 = 3 +(4 * 1023)+ 1。
So, suppose you're copying a large number of bytes (say, 4096 of them) from address 0x12345 to address 0x22345, and that the "word size" is 4 bytes. If we first copy three bytes, the addresses will now be 0x12348 and 0x22348. At this point we can copy just 1023 4-byte words, one word at a time, without tripping over any alignment issues. After that we'll have one remaining byte to copy, because 4096 = 3 + (4 * 1023) + 1.
这一切都使得假设字节都单独寻址,加载和存储字时也是如此。这种假设在某些机器上虚假的:例如,旧的通用数据MV10000 CPU会处理字用字地址,这实质上是字节除以二地址。 (这是因此不可能解决一个字跨越两个字节:在位置0字有字节地址0和1,但字地址0;在位置1的词有字节地址2和3;在位置2字有字节地址4和5;等等),在这样的机器上,你可能需要使用不同版本的bcopy.c的
This all makes the assumption that bytes are all addressed individually, even when loading and storing "words". This assumption is false on some machines: for instance, the old Data General MV10000 CPU would address "words" using "word addresses", which are essentially byte addresses divided by two. (It's thus impossible to address a "word" that spans two bytes: the word at location 0 has byte addresses 0 and 1 but word address 0; the word at location 1 has byte addresses 2 and 3; the word at location 2 has byte addresses 4 and 5; and so on.) On machines like this, you may need to use a different version of bcopy.c.
正如@Alex指出,异或只是确保它实际上是可能的对准两个地址。如果你从0x12345复制到0x22345,它是;但如果你从0x12345复制到0x22344,这两个地址永远不会排队。
As @Alex noted, the XOR is just making sure that it is actually possible to align the two addresses. If you're copying from 0x12345 to 0x22345, it is; but if you're copying from 0x12345 to 0x22344, the two addresses will never line up.
这篇关于如何理解的仿生bcopy.c这code段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!