Unithread SBCL uses a shallow binding scheme: the current value of a symbol is stored directly in its value slot. Accessing specials is pretty fast but it's still a lot slower than accessing lexicals.
With multithreading it's slightly more complicated. The symbol's value
slot contains the global value and each symbol has a
slot that - when it's first bound - is set to a unique index of the
thread local area reserved for this purpose. The tls index is
initially zero and at index zero in the tls
NO-TLS-VALUE-MARKER is different from
UNBOUND-MARKER to allow
PROGV to bind a special to no
value locally in a thread.