<!--
{
  "documentType" : "article",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/adjusting-for-gpu-memory-bandwidth-tradeoffs",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Adjusting for GPU memory bandwidth tradeoffs"
}
-->

# Adjusting for GPU memory bandwidth tradeoffs

Choose a suitable GPU and memory storage mode for tasks based on that GPU’s memory bandwidth on a Mac.

## Discussion

GPU memory *bandwidth* is a measure of the data transfer speed between a GPU and the system across a bus, such as PCI Express (PCIe) or Thunderbolt. It’s important to consider the bandwidth of each GPU in a system when developing your high-performance Metal apps. A GPU that’s powerful on its own may not be the optimal choice for certain tasks if it has a relatively low bandwidth connection to the system.

### Consider how a GPU connects to the system

A GPU’s bandwidth largely depends on the bus that connects it to a system:

- An *external* GPU connects to a system though an external Thunderbolt 3 bus.
- A *discrete* GPU is a built-in GPU that has video memory (separate memory that only the GPU can access) and connects to a system through an internal PCIe bus.
- An *integrated* GPU is a built-in GPU that uses system memory and shares the bus with the CPU.

![A system diagram that shows an iMac Pro and its connections to both a built-in discrete GPU and an external GPU. The discrete GPU connects to the iMac through an internal PCIe bus, and the external GPU connects through an external Thunderbolt 3 bus.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-1@2x.png)

A discrete GPU’s PCIe bus can have 8 or 16 memory lanes — or PCIe x4 or PCIe x16, respectively — depending on the GPU and Mac model. Transferring data between the system and an external GPU can take more time than with a built-in GPU because external GPUs typically have a lower bandwidth connection, such as Thunderbolt 3.

![A horizontal bar chart that shows the relative bandwidths of Thunderbolt 3 (1x), PCIe with 8 lanes (2x), and PCIe with 16 lanes (4x).](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-2@2x.png)

Additionally, transferring data from one GPU to another can be even more expensive because the system can’t transfer data directly between GPUs. Instead, the process typically requires copying data to system memory before copying it again to the destination GPU.

### Select the appropriate storage mode for your resources

You can minimize the bandwidth costs — the number of data transfers across a bus — by selecting an appropriate storage mode for your app’s resources. For more information about selecting a storage mode for specific GPUs, see [Choosing a resource storage mode for Apple GPUs](/documentation/Metal/choosing-a-resource-storage-mode-for-apple-gpus) and [Choosing a resource storage mode for Intel and AMD GPUs](/documentation/Metal/choosing-a-resource-storage-mode-for-intel-and-amd-gpus). Metal uses a resource’s storage mode to determine which memory location to save it in. The storage mode options for a resource include the following:

- [`MTLStorageMode.shared`](/documentation/Metal/MTLStorageMode/shared): Shared resources reside in system memory and are slow to access for discrete and external GPUs.
- [`MTLStorageMode.private`](/documentation/Metal/MTLStorageMode/private): Private resources reside in video memory and are fast to access for discrete and external GPUs.
- [`MTLStorageMode.managed`](/documentation/Metal/MTLStorageMode/managed): Managed resources reside in both system and video memory (dual copies) and are fast to access for discrete and external GPUs.

Discrete and external GPUs have the highest data transfer costs when they access a shared resource because their access to system memory is relatively slow.

![A system diagram that doesn’t recommend a setup where a discrete GPU and an external GPU each store a shared resource in system memory instead of in their dedicated video memory (discrete and external memory, respectively) over a direct, fast connection. Both GPUs and the CPU can access system memory, and the other GPU’s resource, through different connections: The discrete GPU connects through an internal PCIe connection, the external GPU connects through an external Thunderbolt 3 connection, and the CPU connects directly to system memory.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-6@2x.png)

Private resources have the lowest data transfer costs with discrete and external GPUs because their exclusive access to video memory is relatively fast.

![A system diagram that recommends a setup where a discrete GPU and an external GPU each store a private resource both in their dedicated video memory (discrete and external memory, respectively) over a direct, fast connection. Both GPUs and the CPU can access system memory through different connections: The discrete GPU connects through an internal PCIe connection, the external GPU connects through an external Thunderbolt 3 connection, and the CPU connects directly to system memory.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-7@2x.png)

Managed resources can have modest data transfer costs for discrete and external GPUs. The CPU (and an integrated GPU) have quick access to the copy in system memory, and the other GPUs have quick access to the copy in their video memory.

![A system diagram that recommends a setup where a discrete GPU and an external GPU each store a managed resource both in its dedicated video memory (discrete and external, respectively) over a direct, fast connection, and in system memory. Both GPUs and the CPU can access system memory through different connections: The discrete GPU connects through an internal PCIe connection, the external GPU connects through an external Thunderbolt 3 connection, and the CPU connects directly to system memory. Each GPU can access the other GPU’s managed resource by using the system memory’s copy of that resource.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-5@2x.png)

You can keep the copies in sync by efficiently running sparse blit operations (see [Synchronizing a managed resource in macOS](/documentation/Metal/synchronizing-a-managed-resource-in-macos)).

### Render a drawable on the same GPU that drives the destination display

In Metal, a *drawable*, represented by [`MTLDrawable`](/documentation/Metal/MTLDrawable), is a type that bridges Metal and <doc://com.apple.documentation/documentation/QuartzCore>. Each drawable contains a texture that your apps can render with Metal and then present on a device’s display using Core Animation.

Presenting a drawable on a display can have significant bandwidth costs if the drawable belongs to a GPU that doesn’t drive the display. Only one GPU can drive a display, whether it’s built in or external, and the fastest path to present a drawable to a display is to render that drawable with the same GPU that drives the display. Otherwise, the system has to transfer the drawable from the GPU that renders it to the GPU that drives the display.

For example, take a Mac that has both a discrete GPU and an external GPU that’s driving an external display. If your app renders a drawable with the discrete GPU, the system has to transfer the drawable to the external GPU through the Thunderbolt 3 bus to present it on the external display. You app can avoid this transfer by rendering the drawable with the external GPU because it’s also driving the drawable’s destination display.

![A system diagram that shows two possible pathways for a drawable, starting from either the external GPU or the discrete GPU. The diagram recommends the pathway that uses the external GPU to render a drawable because it’s the same GPU that’s driving the external display. The diagram discourages rendering a drawable with the discrete GPU when the external GPU is driving the display because that forces the system to transfer each drawable over the Thunderbolt 3 bus.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-4@2x.png)

Similarly, Mac systems with multiple built-in GPUs may need to transfer a drawable that one GPU renders if a different GPU drives the destination display. For example, imagine a MacBook Pro with automatic graphics switching is currently driving the built-in display with the integrated GPU. If your app uses the discrete GPU to render a drawable, the system has to transfer the drawable’s contents to the integrated GPU over the internal PCIe bus. Your app can avoid this transfer by rendering the drawable with the integrated GPU when it’s driving the internal display.

![A system diagram that shows two possible pathways for a drawable, starting from either the integrated GPU or the discrete GPU. The diagram recommends the pathway that uses the integrated GPU to render a drawable because its the same GPU that’s driving the built-in display. The diagram discourages rendering a drawable with the discrete GPU when the integrated GPU is driving the built-in display because that forces the system to transfer each drawable over the PCIe bus.](images/com.apple.metal/adjusting-for-gpu-memory-bandwidth-tradeoffs-3@2x.png)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)