Mid-2012 13" MacBook Pro + [email protected] (AKiTiO Node via TB3->TB2 adapter) + Linux Mint 19 | Build Guide + Benchmarks [nu_ninja]
Since Linux is so diverse, I want to first give the basic system conditions under which I believe this build guide will be applicable.
+ Computer and eGPU connected over Thunderbolt (any version)
+ AMD graphics card using the amdgpu open source driver (GCN 1 or newer)
+ An external monitor (or possibly headless display adapter)
+ A Linux distro with kernel 4.15 or higher
+ A desktop environment using X
- Wayland not yet working for me (Wayland support is possible, don't know of an easy solution yet. Also see note after step 2)
- dGPU setups may be more complicated
- Internal display is very stuttery when no external display is connected. With external display, it's not stuttery though screen tearing may be noticeable.
For this specific build, I used a Mid-2012 MacBook Pro (Macbook Pro 9,2) connected to a Akitio Node enclosure with a MSI RX 460 graphics card over an Apple Thunderbolt 3->2 adapter with Linux Mint 19 running both the Cinnamon and Gnome desktops.
Instead of following steps 3 and 4 of this guide, you should use sebulon's gswitch script. This gives you a fully GUI way to switch between using the eGPU and internal graphics. Definitely check out the linked thread and github page before installing, but for convenience, I've quoted the relevant commands to get you started from the PPA.
sudo add-apt-repository ppa:karli.sjoberg/gswitch-ppa sudo apt-get update sudo apt-get install -y gswitch-gui
0) Install and configure a Linux distribuiton:
Any distro (with kernel 4.15+) should work. I used Linux Mint 19 which installed mostly smoothly except for it messed up my Windows 10 installation. I had to remove the hybrid MBR it created and repair the windows bootloader to get both OSes running side by side.
1) Plug in eGPU and authorize it:
For Thunderbolt 2 and 3, devices must be authorized before they'll work. On most user-friendly distros this is now as simple as clicking authorize when it prompts you to. The manual method of authorizing devices is described in Da_Blitz's advanced guide. My setup is Thunderbolt 1 so no authorization was needed.
2) Verify eGPU is now connected:
Using the command "lspci | grep ' VGA '" in the terminal should now show your eGPU when it's connected. Note the string of numbers at the beginning of each line is the PCI bus ID in hexadecimal.
If the eGPU is not appearing, ensure the proper drivers are installed. If the eGPU is working as the primary graphics device, congrats, you're done! Otherwise we'll need to continue to the next step.
A Note about DRI_PRIME=1:
This command can be used to set the eGPU as the default renderer. Thus, steps 3 and 4 could be replaced by simply running "export DRI_PRIME=1" at startup. However, I believe that this does not set the eGPU as "primary gpu". As a result, on my Thunderbolt 1 setup, using only the DRI_PRIME=1 command makes the eGPU output very stuttery so this alone isn't a good solution for me. Those with Thunderbolt 3 setups may see better results so I'd try using it. This command might also work as a solution in Wayland.
3) Use an X config file to make the eGPU the primary GPU
I used the Reverse PRIME method to set the eGPU as primary and also get the internal display working. If you prefer clamshell mode with no internal display output, a similar config file without the iGPU references should work. I created a file in /etc/X11/xorg.conf.d with the following:
Section "ServerLayout" Identifier "egpu" Screen 0 "amdgpu" Inactive "intel" EndSection Section "ServerLayout" Identifier "laptop" Screen 0 "intel" Inactive "amdgpu" EndSection Section "Device" Identifier "amdgpu" Driver "amdgpu" BusID "PCI:10:0:0" #BusID in decimal, convert from hex # Option "AllowEmptyInitialConfiguration" # Option "AllowExternalGpus" EndSection Section "Screen" Identifier "amdgpu" Device "amdgpu" EndSection Section "Device" Identifier "intel" Driver "modesetting" BusID "PCI:0:2:0" EndSection Section "Screen" Identifier "intel" Device "intel" EndSection
Note the BusID is the string of numbers before the eGPU line of the output of the lspci command, but in decimal instead of hex.
This config file will automatically start X in "egpu" layout. An X server can be started in the "laptop" layout by killing X and restarting it with "startx -- -layout laptop" or by following the next step.
4) Automate switching of X config files to allow boot with or without eGPU
The X server won't start without the primary gpu so booting normally without the eGPU will likely give you a black screen or a non-graphical (text interface) session. Here's my method of getting around that. Create a second config file in /etc/X11/xorg.conf.d with the following:
Section "ServerFlags" Option "DefaultServerLayout" "laptop" EndSection
for reference, I named mine "01-laptop.conf". I also created a folder called "inactive" in the same place and moved the new config file into it. Moving "01-laptop.conf" into and out of the "inactive" folder sets whether or not the eGPU setup is used. Finally, I then made a script in /etc/init.d to automatically check for the eGPU and move around the config files accordingly on startup.
#!/bin/sh #Script should be safe as long as DIR and FILE don't point to anything valuable DIR=/etc/X11/xorg.conf.d FILE=01-laptop.conf TEST=$(lspci | grep -c " VGA ") #Check TEST against number of gpus including egpu if ([ $TEST -eq 2 ]); then #eGPU Connected if ([ -e $DIR/$FILE ]); then rm $DIR/$FILE fi else #No eGPU or unexpected number/output if ([ -e $DIR/$FILE ]); then break else if ([ -e $DIR/inactive/$FILE ]); then cp $DIR/inactive/$FILE $DIR/$FILE fi fi fi
give the script execution rights ("sudo chmod +x script-name") and link it to your default runlevel (5 in my case) with the command "sudo ln -s /etc/init.d/script-name /etc/rc5.d/S15script-name". Obviously this script has to create and delete system files so use at your own risk. Thanks to this random Polish blog for inspiring this solution.
eGPU accelerated: Internal display, External display:
Clamshell (External display, no internal output):
I see a clear improvement in performace over iGPU so eGPU is clearly working. Note a significant improvement in clamshell mode.
However, I wanted to see exactly how well the eGPU is working in Linux vs Windows or macOS (which I also have installed).
Seems like raw eGPU performance in Linux is about the same as in Windows according to the synthetic Unigine benchmarks (all ran on OpenGL). Gaming performance is clearly lower however, likely due to a lack of optimization and the effect of DX11/12 APIs over OpenGL.
Don't let this long post fool you. Detection of eGPU in Linux (4.15+) is plug and play. The difficulty is in getting the eGPU as the primary graphics renderer. Intentionally or not, this seems to fit with the likely use case for eGPUs in Linux; that being something like TensorFlow rather than gaming or editing. The good news is, like almost anything in Linux, you can get it working with "a little tinkering".
This X config setup finally give me a hassle-free eGPU setup in Linux, where I don't have to run any commands manually at startup and it works with or without the eGPU. This is nice, as I feel like there's an "Uncanny Valley" effect in UX design where making some things easier can expose the little flaws that annoy you even more. I think this setup finally takes my eGPU experience in Linux past that point.
Of course, this is still a workaround and there are still slight annoyances. Anytime the primary display (set in xrandr or the GUI stystem settings under "Display") is not the display connected to the primary GPU, you can expect stuttering. This seems to pretty much rule out internal display only setups (though I'd love to be proven wrong).
Overall, multi-display and multiple GPUs are still a bit of a sticking point in linux. As a result, I think the easiest mode to try first should be clamshell mode (output only on the external display). You might even try letting X auto detect, skipping the whole X config section, by turnning your computer on and keep it closed throughout the boot process. This, and other more high-level methods (see above note after step 2), should probably be the first attempts for any setup, with more complicated manual configurations only coming as needed.
If you use DRI_PRIME, be sure to set it to the "provider" number listed for the eGPU after running the command:
in my case this was 1, in yours it might be 2 since you have a dGPU.
Great guide and thanks for the performance comparisons!
BTW, I remember seeing a much closer scenario in CS:GO performance (windows vs linux). Have you tried updating mesa? I guess (but haven't checked) linux mint mesa must be a little dated.
Soon I will add my build link or system & eGPU details to this my signature to give context to my posts
Yeah that's probably true. Also those benchmarks were done with the internal display enabled, which seems to have a significant performance impact on this setup for some reason. With the internal display turned off I'd expect a much closer result between windows and linux