DGX Spark vs Jetson Thor

tl;dr: Thor’s 20 SMs with tcgen05+tmem beat the Spark’s 48 SMs on tensor
core GEMM. The Spark has 3x the CUDA cores. Similar power under load,
completely different architectures despite both being “Blackwell.”

specs

                        DGX Spark (GB10)           Jetson Thor
                        ----------------           -----------
GPU                     SM 12.1                    SM 11.0
SMs                     ~48                        20
clock                   DVFS 208-3003 MHz          DVFS 315-1575 MHz
tensor cores            mma.sync                   tcgen05.mma + tmem
smem/SM                 99 KB                      228 KB
CPU                     20 cores                   14 cores
RAM                     128 GB unified             128 GB unified
CUDA                    13.2 / 580.142             13.2 / 580.00

Both Blackwell, both aarch64, both 128GB unified. But the Spark’s SMs are
cut down – less shared memory, no tensor memory (tmem), older mma.sync
instead of tcgen05. The Thor has fewer SMs but each one is the (almost) full design.

sustained tensor cores (the number that matters)

cuBLAS FP16->FP32, 4 streams, 30 seconds continuous per size. Both at
DVFS auto, no tuning, stock config.

N        Spark TF    Thor TF     delta     Spark W    Thor W
----     --------    -------     -----     -------    ------
1024       52.7       74.3       +41%        72         79
2048       77.7       78.3       tie         90         78
3072       81.0       99.5       +23%        86        100
4096       83.9       80.2       -4%         85         86
5120       91.5      104.0       +14%        85         90
6144       84.4       98.6       +17%        85         88
8192       91.9       88.5       -4%         84         88

Thor wins most sizes. Spark wins at 4096 (tile quantization, more below)
and 8192 (more SMs help at scale). Power is similar – both land around
85-100W sustained. The Thor hits 104 TF from 20 SMs. The Spark maxes at
92 TF from 48 SMs. Twice the silicon, less tensor throughput.

isolating the architecture: same clock speed

Locked the Spark to 1575 MHz (Thor’s clock). Removes everything except
per-SM tensor efficiency.

N        Spark TF    Thor TF     Thor/Spark
----     --------    -------     ----------
1024       44.4       74.3         1.7x
2048       60.3       78.3         1.3x
3072       67.9       99.5         1.5x
5120       71.3      104.0         1.5x
8192       73.5       88.5         1.2x

Per SM at 1575 MHz:
Thor: 5.2 TFLOPS/SM
Spark: 1.5 TFLOPS/SM (3.3x less)

tcgen05 + tmem + 228KB smem = 3.3x more tensor work per SM per clock.
The Spark compensates with 2.4x more SMs and higher clocks. Gets close
but never ahead on tensor.

Spark at 1575 is interesting on its own: 73.5 TF at 40W and 67C. Running
tensor cores way below their thermal ceiling. Quiet and efficient.

proving it’s the ISA, not cuBLAS tuning

Wrote the same WMMA kernel (mma.sync + shared memory tiling) for both:

N        Spark TF    Thor TF     ratio
----     --------    -------     -----
1024       10.68       2.98      Spark 3.6x
4096        8.55       2.34      Spark 3.7x
8192        8.14       2.29      Spark 3.6x

Same code, Spark 3.6x. SM count wins when both run the same instruction.

cuBLAS flips it because it dispatches tcgen05.mma on the Thor.

tile quantization: 20 SMs = spiky performance

Thor’s numbers are lumpy. Burst benchmarks (not sustained) make it obvious

N        Spark TF    Thor TF
----     --------    -------
3584        82          117
4096        81           68    (-42%)
4352        87          117
4864        92           52    (floor)
5120        90          137    (ceiling)

52 to 137 TF, 2.6x swing. Tiles don’t divide evenly across 20 SMs at
certain sizes. Spark with 48 SMs stays in a 76-92 band. Under sustained
load the dips smooth out but don’t disappear. Real model layers will hit
unlucky dimensions.

clock scaling (Spark)

Sustained tensor at each setting:

MHz      TFLOPS    Watts    TF/W     Temp
----     ------    -----    ----     ----
1575      73.5      40W     1.84      67C
2000      80.9      42W     1.93      68C
2200      83.5      69W     1.21      70C
DVFS      85.9      88W     0.98      80C
2600      86.0      87W     0.98      81C

Saturation hits hard above 2200. Going from 2000 to 2600 buys 6% tensor
throughput for 2x the power draw. The firmware governor settles around
2200-2400 under sustained load anyway.

2200 is the sweet spot for inference serving: 97% of peak, 20W less,
10C more thermal headroom. Locked clocks also kill DVFS ramp-up jitter
on cold requests.

For power-constrained setups, 2000 MHz at 42W is hard to argue with.
1.93 TF/W is double the efficiency of running wide open.

CPU cores: don’t matter for tensor

Offlined cores on both machines. Thor tensor performance is identical
from 14 cores down to 1. tcgen05+tmem is fully autonomous.

Spark shows ~8% sensitivity on naive CUDA core kernels at large N (CPU
helps manage unified memory traffic) but cuBLAS tensor is flat.

thermals

                Spark             Thor
idle:           39C / 11W         36C / 8W
sustained:      79C / 85W         76C / 88W
limit:          90C               plenty

Both comfortable. Spark runs 3C hotter with 11C to the limit. Not a
problem unless your room is 30C+.

On the Thor, jetson_clocks (locked 1575) sits at a flat 74-78C. DVFS
auto swings 56-76C – 18C cooler at light load, same at heavy. Pick
predictable or pick cool idle.

Spark setup and WiFi (MT7925)

First boot gotcha: the Spark ships with the system clock wrong and WiFi
doesn’t connect until the clock is right (WPA3 auth fails with bad
timestamps). You need to hold ESC during boot to get into the UEFI
menu, set the correct time, then plug in ethernet for initial setup.
WiFi works after the first apt update + reboot.

Once WiFi is up, the MediaTek MT7925 WiFi 7 adapter has a firmware bug
where 6 GHz MLD connections silently hang. No disconnect event, no
logs, just gone. Lost the machine multiple times running headless before
figuring it out. On a mesh network it also kept roaming to a far AP
that had enough signal to associate but not enough to complete DHCP –
NetworkManager would sit there for 5 minutes before retrying.

What fixed it:

  • pin to 2.4 GHz (nmcli connection modify … wifi.band bg)
  • disable PCI ASPM (modprobe mt7925e disable_aspm=1)
  • disable wifi power save
  • on a mesh network, pin the BSSID to the nearest AP

Stable since.

tuning script: GitHub - eous/dgx-spark-tune · GitHub

2 Likes

this is awesome, thanks.

as a baseline pedestrian thing what about the actual output from vllm or sglang or whatever for a few popular models?

if all you want is inferencing on Nvidia with 128g would thor be a much better buy esp. if it’s on sale? is the question to more clearly illustrate… from 7 to 120b parameters :smiley:

1 Like

Thor is the one you buy when you want to build something or have a specialized case that works well with 20 SM’s.

To show the problem another way.

Tiles well on Thor (5120 hidden_dim):

  • Llama 2 13B, Llama 4 Scout/Maverick, Qwen 2/2.5 14B & 32B, Phi-3 Medium, DeepSeek V2, DeepSeek R1 Distill 14B/32B, InternLM 20B

Worst case for Thor (4096 hidden_dim):

  • Llama 2/3/3.1 7B/8B, Mistral 7B, Mixtral 8x7B, Yi 6B, Phi-3 Small, InternLM 7B

Large enough to amortize on Thor (8192+):

  • Llama 2/3/3.1 70B, Qwen 2/2.5 72B, Command R/R+, Falcon 40B

Awkward dims (not divisible, not large enough to amortize):

  • Qwen 2/2.5 7B (3584), Gemma 2 9B (3584), Gemma 2 27B (4608), DeepSeek V3/R1 (7168), Falcon 7B (4544)

However you do get tcgen05.mma and tmem which means with the right design thor could be a better fit then spark.

===

Spark is the general inference appliance.

1 Like

2 Likes

Sir, thank you for answering my Qs before I even starting stating them (and thank you for the whole thread participants!) Totally changed my purchase priorities!

1 Like