关于数据传送中 address bus 的工作原理
2009-11-25 11:24
211 查看
此贴是由:http://linux.chinaunix.net/bbs/thread-1145097-1-1.html 而引申出来的话题
贴子里,我说了,导致 非 atomic 的因是:跨 boundary 和 对内存做 RMW(read-modify-write) 操作
这里,详细说一说导致跨 boundary 的来龙去脉:address bus 与 data bus 的工作原理。
--------------------------------------------------------------------------------------------
以 Pentium 为例,因为从 Pentium 开始 data bus 是 64 位的,但 address bus 还是 32 位。
1、 32 位的 address bus 实际上在 processor 接口上只有 29 条线,分别为: A31 ~ A3
地址线 A2 ~ A0 是虚的,被强制为 0
因此: 32 位的 addres 形成如下的表格:
address bus(二进制) address(十六进制)
---------------------------------------------------------------------------------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXX000 XXXX XXX0
---------------------------------------------------------------------------------
00000000000000000000000000001000 00000008
00000000000000000000000000010000 00000010
00000000000000000000000000011000 00000018
00000000000000000000000000100000 00000020
... ... ... ...
11111111111111111111111111111000 FFFFFFF8
----------------------------------------------------------------------------------------
这样在硬件层面上保证了 quadword boundary(8 bytes) 边界
2、 看看下面 2 个例子,说明问题
例1、 mov eax, dword ptr [00000007]
这条指令从地址 [7] 的地方读取 doubleword 到 eax, 这条指令是典型的跨 doubleword boundary
processor 会怎么处理呢?
地址值 00000007H = 00000000000000000000000000000111 B
(1)processor 将地址 0000 0000 送上 address bus(32 位)
这是因为:bit2 ~ bit0 被强制为 0, 地址 [0x00000003] 结果为 0x00000000 送上 address bus
(2)processor 使 BE7# = 0,而其它的 BE 为 1(表示读取第 3 号 byte)
然后,processor 将 byte 送到 eax 的低 8 位。 (这是 processor 做第 1 次 read)
(3)processor 将地址 0000 0008 送上 address bus
这是下一个 quadword boundary
(4) processor 使 BE0# = 0,BE1# = 0, BE2# = 0,其它为 1(表示读取第 0、1、2 号 byte)
然后,processor 将这 3 bytes 送上 data bus 交到 eax 高 24 位。(这是 processor 做第 2 次 read)
-----------------------------------------------------------------------------------------------
可以看出,指令 mov eax, dword ptr [00000007] 做了 2 次 read 操作。
这是因为它跨了 doubleword 边界导致。
例2:指令 movq mm0, qword ptr [00000008]
这条指令从地址 [00000008] 读取 quadword 到 mm0(读 64 位数据),这条指令没有跨 quadword 边界
processor 又怎样做呢?
(1)processor 将地址 00000008 送上 address bus(32 位)
00000008 符合 A2 ~ A0 为 0 的规则。它是 quadword 边界值
(2)processor 将 BE0# ~ BE7# 全部置为 0 (表示使用全部 8 个 data path)
然后,processor 将 quadword 送上 data bus(8 个 data path)
(3) 从而完成了一次读取 64 位数据的传送,processor 只做了 1 次 read 工作
这是典型的 quadword boundary 对齐,是属于 atomic 交易。
3、 关于 RMW(read-modify-write)交易,那个贴子里说了
RMW 交易是对 内存进行的。很显然,在 RMW 交易中,地址需要是目标操作数才可能产生。
源操作数是不会产生 RMW 交易的。
4、 很显然非 atomic 是因为 processor 不是做一次性交易。从 跨 boundary 和 RMW 来看。
由于有中间交易,导致有可能会被其它 processor 偷取 address bus 时钟。
贴子里,我说了,导致 非 atomic 的因是:跨 boundary 和 对内存做 RMW(read-modify-write) 操作
这里,详细说一说导致跨 boundary 的来龙去脉:address bus 与 data bus 的工作原理。
--------------------------------------------------------------------------------------------
以 Pentium 为例,因为从 Pentium 开始 data bus 是 64 位的,但 address bus 还是 32 位。
1、 32 位的 address bus 实际上在 processor 接口上只有 29 条线,分别为: A31 ~ A3
地址线 A2 ~ A0 是虚的,被强制为 0
因此: 32 位的 addres 形成如下的表格:
address bus(二进制) address(十六进制)
---------------------------------------------------------------------------------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXX000 XXXX XXX0
---------------------------------------------------------------------------------
00000000000000000000000000001000 00000008
00000000000000000000000000010000 00000010
00000000000000000000000000011000 00000018
00000000000000000000000000100000 00000020
... ... ... ...
11111111111111111111111111111000 FFFFFFF8
----------------------------------------------------------------------------------------
这样在硬件层面上保证了 quadword boundary(8 bytes) 边界
2、 看看下面 2 个例子,说明问题
例1、 mov eax, dword ptr [00000007]
这条指令从地址 [7] 的地方读取 doubleword 到 eax, 这条指令是典型的跨 doubleword boundary
processor 会怎么处理呢?
地址值 00000007H = 00000000000000000000000000000111 B
(1)processor 将地址 0000 0000 送上 address bus(32 位)
这是因为:bit2 ~ bit0 被强制为 0, 地址 [0x00000003] 结果为 0x00000000 送上 address bus
(2)processor 使 BE7# = 0,而其它的 BE 为 1(表示读取第 3 号 byte)
然后,processor 将 byte 送到 eax 的低 8 位。 (这是 processor 做第 1 次 read)
(3)processor 将地址 0000 0008 送上 address bus
这是下一个 quadword boundary
(4) processor 使 BE0# = 0,BE1# = 0, BE2# = 0,其它为 1(表示读取第 0、1、2 号 byte)
然后,processor 将这 3 bytes 送上 data bus 交到 eax 高 24 位。(这是 processor 做第 2 次 read)
-----------------------------------------------------------------------------------------------
可以看出,指令 mov eax, dword ptr [00000007] 做了 2 次 read 操作。
这是因为它跨了 doubleword 边界导致。
例2:指令 movq mm0, qword ptr [00000008]
这条指令从地址 [00000008] 读取 quadword 到 mm0(读 64 位数据),这条指令没有跨 quadword 边界
processor 又怎样做呢?
(1)processor 将地址 00000008 送上 address bus(32 位)
00000008 符合 A2 ~ A0 为 0 的规则。它是 quadword 边界值
(2)processor 将 BE0# ~ BE7# 全部置为 0 (表示使用全部 8 个 data path)
然后,processor 将 quadword 送上 data bus(8 个 data path)
(3) 从而完成了一次读取 64 位数据的传送,processor 只做了 1 次 read 工作
这是典型的 quadword boundary 对齐,是属于 atomic 交易。
3、 关于 RMW(read-modify-write)交易,那个贴子里说了
RMW 交易是对 内存进行的。很显然,在 RMW 交易中,地址需要是目标操作数才可能产生。
源操作数是不会产生 RMW 交易的。
4、 很显然非 atomic 是因为 processor 不是做一次性交易。从 跨 boundary 和 RMW 来看。
由于有中间交易,导致有可能会被其它 processor 偷取 address bus 时钟。
相关文章推荐
- node.js关于传送数据的二三事
- 关于Activity之间传送数据
- 关于在.net通过XML传送数据
- 关于Android 6.0及以上版本用PendingIntent传送数据丢失问题
- 关于c/c++中信号传送数据函数sigqueue的认识
- 关于应用程序数据的备份与恢复
- 关于mysql处理百万级以上的数据时如何提高其查询速度的方法
- 关于2147217913 从 char 数据类型到 datetime 数据类型的转换导致 datetime 值越界 的问题解决方法
- 关于批量数据更新的问题(C#高性能)
- Bundle数据通过Message传送
- 关于Windows与Linux下32位与64位开发中的数据类型长度的一点汇总
- 串口传送数据出错!
- 关于NTKO_office的操作(从数据库中提取数据,写入到NTKO_office_Word中)
- 关于asp.net自动生成树形下拉列表(数据库版)
- 关于Oracle数据和对象的导入导出 [转]
- [Silverlight学习笔记]关于利用WCF RIA Service进行通信并在客户端获取数据
- Android关于手机数据读取联系人数据
- 关于PostgreSQL向数据库表中添加行数据
- [C++]关于数据永久化的思考(不使用数据库)
- 关于使用EL语句来接收servlet给jsp传递及jsp页面之间传递的数据