One wire between them
is not permission to read
连上一根线,
不等于能读到

No hardware background needed. This page is about what that wire gives you — and the one thing it does not. 不需要硬件基础。这一页讲两块芯片之间那根线,到底给了你什么、没给你什么。

CPU 显卡 the card
Two chips on one board, joined by one wire. Under each lies its own book: the list of house numbers for the memory it looks after. Both books start at their own first page, and neither knows what is written in the other. The wire does not change that — this whole page is about the gap between the two. Violet is the CPU's side, and it means that all through this page: we are standing where the CPU stands, holding the book it holds. 一块板上两颗芯片,中间一根线连着。每颗芯片下面摆着自己的一本册子,记的是它管的那片内存的门牌号。两本都从自己的第一页开始记,谁也不知道对面那本上写了什么。那根线改变不了这件事——这一页讲的就是这中间的差。紫色是 CPU 这一侧,全页的紫都是这个意思:我们站在 CPU 的位置上,手里拿的是它那本册子。

Each chip keeps its own book 每块芯片,各有一本册子

地址 addressaddress a house number for one byte of memory 内存里一个格子的门牌号

Each chip looks after its own memory, and numbers it from its own zero. Two books, two number ones. 每块芯片管着自己那片内存,门牌号各自从 0 开始编。两本册子,各有各的 0 号。

CPU 显卡 the card 0 1 2 0 1 2 本机内存的门牌本 the book for its own RAM 显存的门牌本 the book for its video memory
Two chips, two books. Each book runs 0, 1, 2 and on down to its own last cell — so the number 0 appears twice on this page and means two different bytes of memory, in two different places. That is the whole difficulty, and it is already visible here. Real books hold billions of rows; four are drawn. 两块芯片,两本册子。每本都从 0、1、2 一直编到自己那片内存的最后一格——所以这一页上出现了两个 0 号,它们是两个不同地方的两个格子。全部的麻烦就在这儿,这张图里已经能看见了。真的册子有几十亿行,图上画了四行。

Like two neighbourhoods 就像两个小区

Two neighbourhoods, each numbering its houses from one. Build a road between them and the numbers still do not merge. 两个小区,各自从 1 号开始编门牌。中间修一条路,门牌号照样不会合并

Say you live at number 1 on the left. Your neighbour across the road also lives at number 1 — their own number 1. Tell a courier “go to number 1” and they will stop at yours, because yours is the only book they carry. The road does not fix that. Someone has to write the other side's houses into your book, under numbers of your own. 你住左边 1 号。路对面那家也住 1 号——他们自己的 1 号。你跟快递说「送到 1 号」,他会停在你家,因为他手上只有你这本册子。那条路解决不了这件事。得有人把对面那几栋,用你这本册子里的号,另外写进来一次。

The wire is through. The numbers are not. 线是通的,号是不通的

Hand the CPU a number and it looks it up in its own book. The card's numbers are simply not in there. 给 CPU 一个号,它只会在自己那本册子里翻。显卡那本上的号,它这本里根本没有。

CPU GPU CXL 本机内存 its own RAM 给显存开的号段 a range opened for the card 0x8000_0000 显存 its video memory 0x0000_0000 两本,各编各的 two books, numbered separately
Same picture, both halves at once. Up top the wire; below it the two books. The violet arrow is the CPU reading — and it lands inside its own book, on the hatched stretch. That stretch and the card's video memory are one and the same silicon: 0x8000_0000 in the CPU's book, 0x0000_0000 in the card's. Two numbers, one place. Widths here are not to scale, and each book is shown with two ranges where a real one has dozens. 一张图,两半一起看。上面是那根线,下面是两本册子。紫箭头是 CPU 在读——它落在自己那本册子里,落在那段斜纹上。那段斜纹和显卡的显存是同一块硅:在 CPU 的册子上写 0x8000_0000,在显卡自己的册子上写 0x0000_0000。两个号,一个地方。图上段宽不按比例,每本册子只画了两段,真的有几十段。

Open a stretch of your own numbers 在自己那本上,开出一段号

窗口 windowwindow a stretch of your own numbers, set aside for the other side's memory 自己册子上专门留出的一段号,记的是对面的内存

Nothing moves house. Someone just writes the card's memory into the CPU's book, under numbers the CPU already understands. 谁也没搬家。只是有人把显卡那片内存,用 CPU 本来就认识的号,另外记进了 CPU 这本册子。

开之前 before 开之后 after 本机内存 its own RAM 这段空着 nothing here yet 给显存开的号段 a stretch for the card 0x8000_0000 开一段 open a stretch
One book, before and after. The front half is the CPU's own RAM and does not move. The back half was empty; now it is ruled off and marked 0x8000_0000, and every number in there points at the card's memory instead. No byte was copied to make this happen — the numbers were handed out, once, at start-up. Hatching means the same thing everywhere on this page: this stretch is not local. 同一本册子,开之前和开之后。前半截是 CPU 自己的内存,一动没动。后半截原来空着,现在划出来标上 0x8000_0000,这一段里的每个号,指的都是显卡那边的内存。做这件事一个字节都没搬——只是开机时把号分了一次。斜纹在这一页里始终是同一个意思:这一段不是本地的。

Two ways to get the bytes 拿到那些字节,有两条路

This is what the whole page is for: with the stretch open, one ordinary read reaches across. Without it, you copy first, then read your copy. 这一页就是为了这件事:号段开了,一条普通的读指令就够到对面。没开,就得先搬一份到自己这边,再读那份。

CPU 本机内存 local RAM 显存 the card's memory 一步:直接读 one step: read it 两步:先搬一份 two steps: copy first
Same three blocks, two routes. Violet is one step: the CPU issues an ordinary read against a number in the opened stretch, and the wire fetches it. Dashed ink is two: something copies the card's memory into local RAM, and only then does the CPU read — the bytes cross the wire either way, but now they occupy local RAM as well, and the copy is stale the moment the card writes again. Which route you get is decided by whether that stretch was opened at start-up, and nothing in your code can tell the difference by looking at the pointer. 同样三块东西,两条路。紫色那条是一步:CPU 对开出来的那段号发一条普通的读指令,线负责把字节取回来。墨色虚线那条是两步:先有人把显卡的内存搬一份进本机内存,CPU 再读那一份——字节反正都过了那根线,但现在它同时占着一份本机内存,而且显卡一改,这份就旧了。走哪条路,取决于开机时那段号有没有开出来;光看手上那个指针,代码是分不出来的。