2017年12月10日 星期日

簡介 GIC-400

GIC-400 是 GIC v2 架構,它是設計來配合 ARM CPU 的中斷控制器,能相容 TrustZone 和虛擬化架構並最多支持到 8 個 ARM cores,這篇會介紹相關的一些重要觀念。


Fig 1. GIC architecture (Image source: p.23 of  GIC v2.0 spec)


概觀

GIC-400 可以分成四大模塊,分別是 Distributor (GICD_*)CPU interface (GICC_*)virtual control interface (GICH_*) 和 virtual CPU interface (GICV_*),後面兩個模塊是為了虛擬化。

請參考 Fig 1,中斷進入 GIC-400 之後,首先由 Distributor 模塊處理,中斷的類型可以分成三種,說明如下:
  • SGI (Software Generated Interrupt): 它主要在做 CPU 和 CPU 之間的溝通,觸發方式是對 GICD_SGIR 寫入需求的中斷,這樣就能對特定一個或多個 CPU 發出 SGI,interrupt ID 範圍為 0 ~ 15,Linux v4.14 預先定義了 7 個 SGI ID (IPI_*,在 smp.c 內),而 TrustZone software 一般也會占用一些 SGI ID。
  • PPI (Private Peripheral Interrupt): GIC-400 支持 6 個外部 PPI 和 1 個內部 PPI,這 6 個 外部 PPI 包含 Non-secure EL1 physical timer (ID 30)、Secure EL1 physical timer (ID 29)、virtual timer (ID 27) 和 Non-secure EL2 timer (hypervisor timer, ID 26);這 4 個 PPI 一般會和 ARM CPU 的 4 個相對應 timers 接在一起;再加上 2 個電源管理相關的信號中斷。而內部 PPI 是虛擬化環境專用的中斷 (ID 25),一般是在 Guest OS 處理好 hypervisor 發給它的 virtual interrupt 之後,會發這個 PPI 給 hypervisor,請 hypervisor 做後續處理,之後的章節在說明虛擬化時 (),會再詳細地介紹。
  • SPI (Shared Peripheral Interrupt): GIC-400 最多可以支持 480 個 SPI,要通知 CPU 中斷的設備,會有實體連線連接到這個 GIC,這些中斷會按順序安排,最多安排到 Interrupt ID 511 (480 SPI + 16 SGI + 16 PPI),一個 SPI 發到 Distributor 後,可以由 distributor 來決定要通知那幾個 CPU。
中斷經過 Distributor 處理之後,優先權高的中斷會先由 CPU interface 發中斷到對應的 CPU core (Linux 把所有中斷的優先權設成一樣,這樣就不會有巢狀中斷的狀況),CPU 再經由讀取寫入特定 CPU interface 告知 GIC 這個中斷的處理狀況。ARM 官方有兩份關於 GIC-400 的文件,一份是 GIC v2 架構規格書,一份是 GIC-400 技術參考手冊,前者主要說明 GIC v2 的架構、設計如何控制它和這個 GIC 和其它軟體的互動建議,後者是 GIC-400 對 GIC v2 的實現細節,比如 GIC v2 規定 SPI 最多支持到 1020 個 interrupt IDs,而 GIC-400 最多只能支持到 interrupt ID 511。另外,底下的觀念,建議在讀這兩份規格書前要先理解:
  • Banked register: 每個 CPU 都有自己的暫存器,比如某個 PPI 是否要暫時 disable,GIC-400 給每個 CPU 在這個功能上都有自己的設定暫存器,只會 disable 這個 CPU 的中斷,但如果是 SPI 的同樣功能,一但把某個 ID 的 SPI 給 disable 了,就所有 CPU 都收不到了,除了 PPI,SGI 和 SPI 也有某些暫存器有這樣的設計。假如要去設定 CPU 0 的 GICD_IGROUPR0,由於 GICD_IGROUPR0 是 banked register,一般的做法是發軟體中斷 (SGI) 給 CPU ID 0,CPU ID 0 再去寫入 GICD_IGROUPR0 的實體位址,如果是給 CPU ID 1 呢?那就請 CPU ID 1 去寫入 GICD_ISPENDR0 的實體位址,這 2 個 CPU 寫入的實體位址是一樣的嗎?是的!這方面底層的原理請參考 Fig 2,GIC 和 ARM CPU cores 是通過 AXI bus protocol 溝通的,為了 GIC-400,有 6 根特別的信號線 AWUSER[2:0] 和 ARUSER[2:0],把寫入或讀取的 CPU ID 傳給了 GIC-400,這樣 GIC-400 就知道是那個 CPU ID 對它控制了,但這 6 根專門為了 GIC 設計的線,在 GIC v3 之後的架構就丟掉不用了,因為之後的 GIC 版本可以支持到上百個 CPU cores 了。
  • Security banked register: 類似前面 Banked register,在 Secure mode (Secure EL1) 底下,某些 GIC 的 registers 會有另一組和 Non-secure mode 不同的 registers,比如 GICD_CTLR 在 Secure mode 底下有另一組 register 可以決定 Secure interrupt 是否要 enable。AXI 的 AWPROT[0:2] 和 ARPROT[0:2] 可以讓 GIC 知道目前存取的 CPU 是在 secure 、privileged 或 normal protection mode。
  • Security Extensions: 為了支持 ARM TrustZone 的安全環境而增加的模塊,GIC-400 加上了 Security Extensions 之後, 可以設置一些中斷為 Secure interrupt, 而這些中斷一般會設定成發到 Secure world,並且在安全環境才能操作這些中斷相關的 registers,非安全環境下,這些 registers 的存取為 RAZ/WI (Read-as-zero/Write-ignore),後面章節有詳細的介紹 ()。
  • 一個 SOC 的 CPU num、SPI num 、PPI 支持狀況、有多少 Secure interrupt 可以被 lockdown 、是否有支持 Security Extensions 和是否有支持 Hypervisor Extensions 等,這些都是無法被動態設置的,SOC 出廠時都已固定了,在 GICD_TYPER 內查得到這些配置,而規格內提到 unimplemented interrupt,就代表超過 SPI num 的 interrupt ID。
Fig 2. GIC-400 bus overview (Image source: p12 of GIC-400 spec)

Distributor

Distributor 的目的在接收外面進來的中斷信號 (SPI 和 PPI),並把這些中斷轉發到一個或多個 CPU cores,CPU 上的中斷函式會使用 CPU interface (GICC_*)來更新這些中斷的處理狀態,最後由 Distributor 來解除對 CPU 發出的中斷信號,Distributor 的狀態機 (State machine) 和 CPU interface 的控制順序會於下一章節說明 ()。另外值得一提的是,每個中斷 ID 都會有自己的狀態,這些狀態是由 Distributor 來控制並保存的,它們並不是保存在每個 CPU interface 內,一個 CPU 收到中斷,並控制 GIC 的 CPU interface (控制 GICC_* 暫存器),其實並不是更新 CPU interface 的狀態,而是透過 CPU interface 來更新這個中斷於 Distributor 內的狀態。

除了從 GIC 外面發進來的中斷,Distributor 也有介面可以更改每一個中斷的狀態來觸發中斷,一個設置成 Edge trigger 的中斷,只要把它的 Pending 設置起來 (GICD_ISPENDRn),GIC 就會對這個中斷預設的一個或多個 CPU 發出中斷,有些 SOC 會預留一些 interrupt ID,它們並沒有接到真正的設備,但 Distributor 內有留下這些中斷的配置,這些 interrupt ID 就可以拿來做 CPU 和 CPU 或軟件內特別的溝通 (SOC 的技術手冊內有些不連續的 interrupt ID,它們很可能就可以拿來做這些個用途),當然,SGI 是一個更正式的方式,不過 Linux、TrustZone 和 ATF 使用的 SGI ID 會越來越多,因此,就算現在還有空的 SGI ID,未來還可能要跟這些軟件搶

Distributor 的控制介面 (GICD_*) 除了可以更改每一個中斷的狀態之外 (Active 和 Pending),還有設定每個中斷的開關、優先權、Level/Edge trigger、Secure/Non-Secure 和要發到那些 CPU,另外,也提供了查詢中斷支持的狀況。

CPU interface

CPU interface 的目的是做為 Distributor 和 CPU 的介面,如 Fig 1,每個 CPU 都有一套 CPU interface,Distributor 通過它來通知 CPU 中斷,而 CPU 通過它來告知 Distributor 中斷的處理狀況。底下 Fig 3 是 Distributor 內中斷的狀態機,每一個中斷都有自己的狀態,狀態之間的轉換是由外部中斷通知 Distributor 和 CPU 讀寫 GICC_* 暫存器相互作用而發生的。
Fig 3. Interrupt handling state machine (Image from: p42 of  GIC v2.0 spec)

外部中斷分成 Edge trigger 和 Level trigger,底下 Fig 4 和 Fig 5 的 "Interrupt signal from peripheral to GIC" 分別代表 Level 和 Edge trigger interrupt,一般來說,使用 Edge trigger 而 CPU 處理不夠及時的狀況下,GIC 的 Distributor 可以幫忙暫存多個中斷,GIC v2 的狀態機可以暫存兩個中斷,而使用 Level trigger,則適合把多個設備合成一個中斷,在軟體收到中斷之後,再去確認那些硬體需要處理,並在處理好這些硬體的中斷需求之後,把這些硬體的中斷需求清除,在所有中斷需求都清除後,這些硬體聯合一起拉到 GIC 的這一根中斷信號就會取消。

Fig 4 是一般狀況下 Level trigger interrupt 於 Linux GIC v2 driver,配合 GIC 狀態機 (Fig 3) 的時序圖,各信號說明如下:
  • Interrupt signal from peripheral to GIC: 外部設備通知 GIC-400 的信號。
  • Interrupt signal form GIC to core: GIC-400 通知目標 CPU core(s) 的信號,一般來說 Linux 會把所有 SPI 類型的中斷發到 CPU 0。
  • GIC state machine for the interrupt: Distributor 在配合輸入中斷和 Linux 驅動的狀態。
  • Linux GIC driver: 請參考 Linux irq-gic.c 的 gic_handle_irq(),配合底下的說明:
    • Interrupt vector: CPU 一收到 GIC 發出的中斷,CPU 會馬上跳到中斷向量,並執行 Linux 預先註冊好的中斷函式,再跳到 gic_handle_irq()。
    • GIC_CPU_INTACK: 讀取 GIC 的 GICC_IAR,這會得到中斷的 ID,如果中斷已經被讀取,再次讀取會得到無效中斷 ID (spurious ID: 1023,圖中的紅點代表讀到 1023)。
    • GIC_CPU_EOI: 把中斷 ID 寫到 GIC 的 GICC_EOIR,Distributor 會清除中斷 ID 的 Pending 狀況。
    • Clear interrupt bits: handle_domain_irq() 會叫用先前對這個中斷 ID 註冊好的函式,一般來說,這個函式會確認那些設備發出需求,在做完最初步的處理後,會清除它們的中斷需求狀態,全部清除之後,發到 GIC 的中斷就會解除 (deasserted)。
gic_handle_irq() 會讀取中斷 ID,EOI,再叫用使用者的中斷函式,如果中斷函式清除設備需求之後,馬上又有設備發出了中斷需求,讀取 GIC_CPU_INTACK 時會得到有效的中斷 ID,這時會再處理這個中斷,直到讀取 GIC_CPU_INTACK 時得到無效中斷 (1023) 為止。

Fig 4. Level trigger interrupt

Fig 5 為 edge trigger 的狀況,其中 A&P 代表 Active and Pending,類似前面的說明,這裡不再贅述。

Fig 5. Edge trigger interrupt

一般的中斷只需要注意 Distributor 和 CPU interface 的控制,後面兩章的內容,是在有 TrustZone 或 hypervisor 軟體下才需要了解。


Secure interrupt

ARM 的 TrustZone 是為了保護重要軟硬體和資料在 Secure 環境內,任何 Non-secure 的程式都無法存取它們,Secure interrupts 的相關設定和中斷的通知當然也不能被 Non-secure 環境下的程式存取或修改。

在支持 Security Extensions 的 GIC-400,可以把中斷分成兩類,Group 0 為 Secure 環境使用,而 Group 1 為 Non-secure 環境使用,Group 0 的中斷的優先權會比任何 Group 1 的中斷高 (Group 0 會使用低的一半優先值,Group 1 會使用高的一半優先值,越低的值優先權越高),GIC v2.0 的 p80 列出了只能在 Secure 環境下存取的暫存器和 Security banked registers,另外,GICC_A* 是原本 GICC_* 的 Group 0 別名暫存器。如 Fig 6 所示, GICD_IGROUPRn 可以設置每一個中斷 ID 是 Group 0 或是 group 1,GICD_IGROUPRn 只能在 Secure 環境下存取,另外,Group 0 的中斷可以在 Secure 環境下設置 GICC_CTLR 來決定 Secure interrupts 是發出 FIQ 或是 IRQ,一般來說 Secure interrupts 會使用 FIQ,再由 CPU 的 SCR_EL3.FIQ 來決定 FIQ 發到 EL3, 然後由 EL3 進到 Secure world。

另外,GIC-400 可以把 interrupt ID 32 到 63 中的一部分或全部設置成 lockable SPIs (Lockable SPIs 的範圍在 SOC 出廠時就固定,不能動態變更),在 CFGSDISABLE 給高電位時,Lockable SPIs 中斷相關的設定都會被固定,在 Secure 環境也無法更改這些設置。一般在開機時,會在 Secure 環境,由開機相關程式設定好 lockable SPIs 後,就會拉高 CFGSDISABLE,之後的 TrustZone 軟體和整個系統,都無法再更動這些設置,Lockable SPIs 比 Group 0 的保護更嚴謹。


Fig 6. GIC in a secure and virtualization system  (Image source: p.72 of  GIC v2.0 spec)


Virtual Interrupt

虛擬中斷 (Virtual interrupt) 的功能,需要 GIC-400 有 Hypervisor Extensions,而 Hypervisor Extensions 必須依靠 Security Extensions,這個功能是為了支持虛擬化,它可以實現在一套系統上運行多套操作系統的虛擬化環境,如 Fig 7 所示,ARM v8 架構的 EL2 是專門為了虛擬化的運行環境,所有跟需擬化相關的硬體和暫存器,都只能在 EL2 才能存取,並且通過設置 HCR_EL2,可以把原本 ARM 指令集內,無法滿足虛擬化需求的指令 trap 到 EL2 運行。


Fig 7. ARM v8 Execution Levels (Image source: here)

一般的 Hypervisor 環境會把 ARM 的 HCR_EL2.IMO 會設置成 1,此時,所有 IRQ 中斷都會發到 EL2,由 Hypervisor 來處理,Hypervisor 處理過後,再轉發 Virtual IRQ 到 Guest OS 的 kernel (EL1)。更詳細的說,GICC_CTLR.EOImodeNS 會被 hypervisor 預設成 1,中斷會按底下的方式處理,
  1. Hypervisor 一但收到中斷 (使用 GICC_IAR 讀出中斷 ID),就會把中斷 ID 寫入 GICC_EOIR,但此時的 EOI 跟之前不同,它並不會改變中斷的狀態機,只會把這個中斷的優先權降低 (由於 GICC_CTLR.EOImodeNS = 1)。有些中斷如果是 Hypervisor 自己要處理的,會使用 GICC_DIR 來達成原本 EOI 的功能。
  2. 由於這個中斷的優先權被降低了,因此原本相同或較低優先權的中斷就會再被 hypervisor 收下。
  3. Hypervisor 收下所有的中斷後,會判斷這些中斷要發給那個或那些 Guest OS(s),請參考 Fig 6,選定要執行的 Guest OS 後,接下來 hypervisor 會把要給這個 Guest OS 的中斷都寫入 List register (GICH_LRn,GIC-400 共有 4 個,也就是 GICH_LR0 ~ GICH_LR3),並把 GICH_LRn.HW 設成 1。
  4. Hypervisor 會準備好 Guest OS 的環境,然後切換到 Guest OS,Guest OS 一開始執行,會馬上收到中斷 (由於 List register 有 pending interrupts,VIRQ 信號會被提高),GIC 會依 List register 的內容,依次發虛擬中斷 (VIRQ) 給 Guest OS。
  5. Guest OS 使用虛擬的中斷介面 GICV_* 來處理這些中斷 (Guest OS 的程式是寫到 GICC_* 的,但這個地址被 hypervisor 轉到 GICV_*,這樣維持了原本 Guest OS 的程式,Guest OS 不需要知道是否有 hypervisor 的存在),由於 GICH_LRn.HW = 1,在 Guest OS 寫入 GICV_EOIR 時 (同上,Guest OS 的程式是寫到 GICC_EOIR,被 hypervisor 轉址了),CPU interface 會去通知 Distributor 改變這個中斷的狀態機。
  6. 如果 Guest OS 尚未把所有 List register 內的中斷都處理完之前,hypervisor 就要轉換到另一個 Guest OS,hypervisor 會把 List register 的狀態存下來,等下次再讓原本 Guest OS 處理。更詳細的來說,Hypervisor 有自己的 timer,會從 ARM CPU 內定時發出中斷,這個中斷是拉到 GIC 的 PPI ID 26,然後由 GIC 再發出 IRQ 到 ARM CPU 的 EL2,EL2 收到任何中斷,都會中止原本 Guest OS 的執行,然後跳回 EL2 的 hypervisor 執行。
這邊要注意的是,中斷是在 EL2 hypervisor 內被收下,再轉由 EL1 的 Guest OS 去 EOI 這個中斷的。另外,由於 GIC-400 的 List register 只有 4 個,如果要給同一個 Guest OS 處理的中斷不止 4 個,hypervisor 會把 GICH_HCR.NPIE 設成 1,這樣的話,只要 Guest OS 把 List register 的 4 個中斷都處理到沒有 pending interrupt 時,PPI ID 25 就會被發到 EL2,hypervisor 會接下去把剩下的中斷填入 List register,然後反覆到沒有中斷需要再請 Guest OS 處理為止。

為了讓 Guest OS 感覺不到自己是在 hypervisor 的環境下運行,所有 Guest OS 的 GIC 驅動程式會使用的介面,都需要 hypervisor 做特殊處理:
  • Distributor: 跟中斷狀態機相關的,如前面所述,是由 List register 和 Distributor 共同配合完成的,而原本 GICD_* 的功能,hypervisor 會給 Guest OS 操作一套虛擬的暫存器,當 Guest OS 對它們讀寫時,會觸發 Exception (data abort exception),這時會 trap 到 hypervisor 環境,hypervisor 會用軟體模擬對 Distributor 的操作,並把結果返回到 Guest OS。Hypervisor 會使用第二層的 MMU table (2-stage MMU),而 Guest OS 則控制自己第一層的 MMU table,Guest OS 第一層 table 映射到的 GICD_* 的實體位址,被 hypervisor 的第二層 MMU table 再次映射到虛擬地址,因此當 Guest OS 存取時,會發 trap 到 hypervisor。
  • CPU Interface: GICC_* 和 GICV_* 的每個暫存器的相對位址都是一樣的,這樣確保 Guest OS 操作 GICV_* 時,像是在操作 GICC_*,程式不需要修改,Hypervisor 會把 Guest OS 的 CPU interface 重新映射到 GICV_*,而這些暫存器都是 banked registers,也就是不同 CPU 操作相同的 GICV_* 實體地址,會使用到這個 CPU 自己的那份暫存器,而 hypervisor 則可以透過不同的地址去操作不同 CPU 的那份 GICV_* (Alias virtual CPU interface address)。另外,當 Guest OS 去修改 GICV_CTLR.EnableGrp0 和 GICV_CTLR.EnableGrp1 時,hypervisor 可以透過控制 GICH_HCR,來讓這個行為發出 PPI ID 25,通知 hypervisor 做相對應的處理。

2017年11月6日 星期一

你現在的決定也許可以改變過去的歷史--量子延遲選擇抺除實驗

本篇主要是說明一些上世紀的量子力學中對光子相關實驗的奇怪而荒誕的結果,其中,最後一個實驗,量子延遲選擇抺除實驗發現,在量子的世界,你現在的決定似乎可以改變過去的結果,為了理解最後一個實驗,我們先說明兩個相關的實驗,雙縫實驗和延遲選擇實驗。

雙縫實驗 (Double-slit experiment)

雙縫實驗有很多版本,綜合了多個實驗,其中最奇特的發現是,對光子的觀察,會改變光子的物理現實,而且,這個特性不止是光子,包含電子、中子、質子、介子等,都有類似特性。

底下 Fig 1 是水波穿過兩個洞的現象,可以看到水波紋之間會互相干涉,如果把水換成光,也會有類似的效果。
Fig 1. 水波通過雙綘Image Source: here

Fig 2 顯示出雷射光子經過雙縫後打在屏上的結果和水經過兩個縫的干涉條紋類似。如果想在家實驗光的波紋,可以用雷射筆,加上兩個間隔很近的小洞也可以看到這個結果。

Fig 2. 雷射光的干涉模式Interference pattern, image source: here

上述結果,科學家原本認為是光子之間會互相干涉,但 1909 年,傑弗里·泰勒爵士以更精緻的實驗發現,就算一次只發射一個光子,光子自己也會好像跟自己產生干涉反應一樣,也就是,一個光子會同時通過兩個縫,並自己干涉自己,而產生干涉反應,一般對此的解釋是,光子在打到屏之前為波的狀態,而非粒子的狀態。下圖 Fig 3 是一個一個的電子通過雙縫後,打到探測屏上,累積一陣子後的結果。

Fig 3. 粒子的干涉模式(Interference pattern, image source: here

但是,只要雙縫的前面加上探測器去探測任何一個縫,看光子是從那個縫過去的,結果干涉模式(Interference pattern)的干涉紋就會消失,轉而成為坍塌模式(clump pattern),由於一但偵測了光子,就知道光子從那個縫過去的,它不可能再同時從兩個縫過去,並自己干擾自己,光子這時從波轉成粒子的狀態,坍塌後的結果就類似把一個一個的小球隨機地從兩個縫射過去,這樣小球打在屏上的印記就不再有類似水波紋的干涉現象,如 Fig 4 所示。(我們用"加上探測器去偵測光子"來減化說明,事實上,可能的做法是改變光子的極性,來確定光子是從那個縫過來,我們看電影的3D眼鏡,就可以過濾不同極性的光)。


Fig 4. 坍塌模式clump pattern

有些人懷疑這個實驗認為它是由於觀察光子時,必須要使用其它粒子去和光子作用(或是改變光的極性),才能觀察出結果,因此干擾了光的波型態,讓光子坍塌了,但下一個要介紹的實驗更進一步得知,並不需要去干擾光子,而是只要邏輯上,不能推論出光子的確定路徑,光子就會是干涉模式,只要能確定路徑就會坍塌,不需要用什麼手段來和光子作用才會有這個結果。

 惠勒延遲選擇實驗 (Wheeler's Delayed-Choice Experiment)

底下 Fig 5 就是惠勒延遲選擇實驗的架構,一個光子從左下角出發,經過一個半透鏡 (BS1),光子有一半的機會,會往上走(path 1),也有一半的機會往右走(path 2),不論往上還是往右走,都會碰到一個反射鏡(mirror),然後走到右上角的可控透鏡(BS2),實驗者可以控制這個透鏡為半透,或是全透明,光子最後會打在 D1 和 D2 的偵測屏上。

Fig 5. Wheeler's Delayed-Choice ExperimentImage source: here

在 BS2 設為半透的狀況下,一但 D1 或 D2 偵測到光子時,這個光子可能有 1/2 的機會是從 path 1 來的,也有 1/2 機會是從 path 2 來的,由於無法推論它到底是走 path 1,還是走 path 2,D1 和 D2 就會顯示成干涉模式。類似前面雙縫實驗,一個不能再被分割的光子,要不就走 path 1,要不就走 path2,但它的結果卻像是它同時走了 path1 和 path2, 並自己干涉自己,而產生了干涉模式,也就是說光子這時為波的型態。

在 BS2 被設為透明的狀況,一但在 D2 偵測到光子時,它必定是從 path 1 來的,因而坍塌成一點,D1 也是類似的狀況,也就是 D1 和 D2 顯示的結果為光子都打在中心上,不再顯示干涉模式,這時光子為粒子型態。

這個實驗最奇怪的地方在於,就算光已經經過了 BS1,只要光尚未通過 BS2,這段時間去改變 BS2 的透明度,實驗結果會依 BS2 最後的結果來決定 D1 和 D2 的狀況。如果 BS2 一開始設置為全透明,那光子要不就走 path 1,要不就走 path2,按前面的實驗結果,這時的光應該是粒子型態,怎麼會一但把 BS2 改為半透明後,打在 D1 和 D2 上的結果成了波型態?反過來,BS2 如果一開始設置為半透明,那按之前的實驗,光會同時走 path 1 和 path 2,那它應該是波的型態,怎麼會一但把 BS2 改為全透明,結果卻是顯示粒子型態?比較可能的解釋是,光子的粒子型態和波型態是同時存在,按是否能從邏輯上可以被觀察到它的路徑來決定最後顯示為粒子或是波的型態。

利用這些詭異的特性再加上量子糾纏,2000 年 Yoon-Ho Kim 等人做了一個更加毀人三觀的實驗,量子延遲選擇抺除實驗(Delayed choice quantum eraser)。

量子延遲選擇抺除實驗 (Delayed choice quantum eraser)

請參考 Fig 6,底下是整個實驗的設置和結果,
  1. 在左邊 BBO 之前,和前面雙縫實驗一樣,Laser beam 一次射出一個光子,經過兩個縫。
  2. BBO 會把原本的光子,纏繞上另外一個光子。
  3. D0 掃描 x 軸來偵測光子,如果沒有前面第二步,這個實驗會類似雙縫實驗,測出來的會是干涉模式。
  4. 另一個纏繞的光子,往下走到 PS 折射鏡,而 BSb、BSa 和 BSc 是三個分光鏡,光子在分光鏡上有 50% 的反射機會,也有 50% 的穿透機會。
  5. 如果 D4 偵測到光子,由於這個光子是和另一個打在 D0 上的光子是相互纏繞的,因此,可以知道這兩個光子走的路徑是紅色的 path,而由於光子的 path 被確定,D0 會呈現坍塌的粒子模式(如同 Fig 7 所示),D3 和 D0 也是類似的結果。
  6. 如果 D1 偵測到光子,這個光子有 50% 的機率是走紅色路徑過來,也有另外 50% 的機率是走藍色路徑過來,由於無法確定光子是走那個路徑,因此,D0 會呈現干涉模式(如同 Fig 8 所示),D2 和 D0 也是類似的結果。
  7. 光從 BBO 到達 D0 和光從 BBO 到達 D1、D2D3 或 D4 的距離相差 2.5m,也就是光走 8.3ns 的時間,而打在 D0 上的光子,被 8.3ns 之後打在 D1D2D3 和 D4 上的纏繞光子影響了。
Fig 6. Delayed choice quantum eraser experiment.(Image source: here


Fig 7. D0 + D4 組合結果,D0 偵測的 X 座標為 X 軸,D4 偵測到的時間為 y 軸(Image source: here

Fig 8. D0 + D1 組合結果(Image source: here

這個實驗的奇怪之處在於,光子走到 D1 ~ D4 所需要的時間是比到 D0 的時間還要久的(原本實驗是差 2.5m 距離,也就是光走 8.3ns 的時間,如果把距離加大到 300000KM,也就是 1光秒,也會仍舊有同樣的結果),如果說因為後來的 D1 ~ D4 是否能推測出光的路徑而造成前面的 D0 結果成為干涉或坍塌模式,那不就因果倒置?也就是後來的事影響了前面的結果?如果要按時間的順序來推論,那當一個光子打在 D0 時,已經決定了另一個纏繞的光子會打在 D1 ~ D4,那這個實驗只要把 BSa 和 BSb 改成可以人為來控制全透明或全反射(可以把相差的距離加大到人可以反應的時間,或是人事先決定一連串 BSaBSb 的開關順序),那就更怪了,光子打在 D0 時,就已經決定了操作的人會選擇把 BSa 或 BSb 設成全透明或全反射了?到底那個是因,那個是果?光子不但可以不受空間限制(兩個纏繞的光子,可以不受空間的限制即時的相互影響),是否也有可能不受時間的限制?(這裡也是非常簡化的說法,其實原本的實驗,一個光子是無法有任何推論的,必需要打上大量的光子,才有比較高能推論的機率,可以參考 Fig 7 和 Fig 8)。

光子的目的

也許宇宙的每個基本元素,甚至宇宙本身,都有一個最終目的,為了達成這個目的,會有一些特別的方法,光子的目的很可能就是以這個宇宙最快的方式從 A 點走到 B 點,它是怎麼做到的?它的做法是同時走無限條路徑,並在最快的路徑確定後坍塌,因為光的這個目的,造成了它在水中的折射,這個效應是由於光在水中的速度比較慢,因此,它會在速度比較快的空氣中走比較長的距離,而在速度比較慢的水中,走比較短的距離,如同 Fig 9 所示。


Fig 9. 光的折射 (Image source: here)

量子的世界和現實世界的關連性

量子構成了現實的世界,但量子世界又跟現實的世界非常的不同,兩者到底有什麼樣的連結一直是物理學家想知道的答案,古典物理學是建位在連續的基礎上,但量子的發現,把這個基礎給摧毀了,普朗克給出了最小的時間和矩離,小於這個時間和距離將無法被區別,也就是現實的時間和距離都並不是連續的,另外,量子的不確定性也毁掉了確定性的古典物理。

在量子的世界,薛丁格方程式(Schrödinger equation)很好的描述了一個量子的疊加態 (superposition),但是當我們想計算出更多量子的狀況時,由於量子之間會相互影響,因此系統的計算量會依量子數量呈指數級來增長,也就是,它是 NP-hard 的問題,目前的計算機,最多也只能算到幾千個量子,但是現實世界(宏觀世界)1 克氫氣約是 10^24 個量子(Avogadro's number),也就是說,如果要計算出來的話,要花 2^10^24 的計算複雜度,近似成 10 為底的話是 10^(3x10^23),這樣就算是計算到宇宙毁滅,100 億年之後(3.15x10^17秒),而且,計算機的速度也達到物理的極值,一個普朗克時間就計算一單位,也就是 1 秒算 10^43 次,這樣也只能計算 10^61 次,這個數字跟 10^(3x10^23)  比起來還是跟本不在同一個數量級上(10^(3x10^23)/10^61 = 10^(3x10^23-61))。上面的論述是以 1 克氫氣來算,如果以目前宏觀世界可以觀測到的最小物質,約 10^12 個量子,結論仍舊一樣:10^(3x10^10)/10^61 = 10^(3x10^10-61)。

利用量子會同時試無限條路徑的特性,它對類似最短迷宮路徑的問題(也是一個 NP-hard 的問題,數學可以証明,所有 NP-hard 的問題,都是可以相互轉換的),可以用光走最短路線的時間就找到答案(這個對計算機是 NP 問題, 對量子來說是 O(length)),但由於這個迷宮必須是物理上真正的迷宮,而不能只是存在電腦的一串資料,無法一般化解決這個問題,但是量子的行為是有邏輯性的,因此,的確可以拿它來做一些計算,對我們來說,那麼多量子互動形成的宏觀世界;這個就算我們用儘全銀河系的質量轉換成的能量來計算,也是連最微小的物質都無法算得出的世界;卻是運行的那麼順,也許有一天,這樣的運算能力,能夠被我們所利用。