dlandon Posted May 12, 2016 Share Posted May 12, 2016 (edited) There have been several posts on the forum about VM performance improvements by adjusting CPU pinning and assignments in cases of VMs stuttering on media playback and gaming. I've put together what I think is the best of those ideas. I don't necessarily think this is the total answer, but it has helped me with a particularly latency sensitive VM. Windows VM Configuration You need to have a well configured Windows VM in order to get any improvement with CPU pinning. Have your VM configured as follows: Set machine type to the latest i440fx.. Boot in OVMF and not seaBIOS for Windows 8 and Windows 10. Your GPU must support UEFI boot if you are doing GPU passthrough. Set Hyper-V to 'yes' unless you need it off for Nvidia GPUs. Don't initially assign more that 8 GB of memory and set 'Initial' and 'Max' memory at the same value so memory ballooning is off. Don't assign more than 4 CPUs total. Assign CPUs in pairs to your VM if it supports Hyperthreading. Be sure you are using the latest GPU driver. I have had issues with virtio network drivers newer than 0.1.100 on Windows 7. Try that driver first and then update once your VM is performing properly. Get the best performance you can by adjusting the memory and CPU settings. Don't over provision CPUs and memory. You may find that the performance will decrease. More is not always better. If you have more than 8GB of memory in your unRAID system, I also suggest installing the 'Tips and Tweaks' plugin and setting the 'Disk Cache' settings to the suggested values for VMs. Click the 'Help' button for the suggestions. Also set 'Disable NIC flow control' and 'Disable NIC offload' to 'Yes'. These settings are known to cause VM performance issues in some cases. You can always go back and change them later. Once you have your VM running correctly, you can then adjust CPU pinning to possibly improve the performance. Unless you have your VM configured as above, you will probably be wasting your time with CPU pinning. What is Hyperthreading? Hyper threading is a means to share one CPU core with multiple processes. The architecture of a hyperthread core is a core and two hyperthreads. It looks like this: HT ---- core ---- HT It is not a base core and a HT: core ---- HT When isolating CPUs, the best performance is gained by isolating and assigning both pairs for a VM, not just what some think as the '"core". Why Isolate and Assign CPUs Some VMs suffer from latency because of sharing the hyperthreaded cpus. The method I have described here helps with the latency caused by cpu sharing and context switching between hyperthreads. If you have a VM that is suffering from stuttering or pauses in media playback or gaming, this procedure may help. Don't assign more cpus to a VM that has latency issues. That is generally not the issue. I also don't recommend assigning more than 4 cpus to a VM. I don't know why any VM needs that kind of horsepower. In my case I have a Xeon 4 core processor with Hyperthreading. The CPU layout is: 0,4 1,5 2,6 3,7 The Hyperthread pairs are (0,4) (1,5) (2,6) and (3,7). This means that one core is used for two Hyperthreads. When assigning CPUs to a high performance VM, CPUs should be assigned in Hyperthread pairs. I isolated some CPUs to be used by the VM from Linux with the following in the syslinux configuration on the flash drive: append isolcpus=2,3,6,7 initrd=/bzroot This tells Linux that the physical CPUs 2,3,6 and 7 are not to be managed or used by Linux. There is an additional setting for vcpus called 'emulatorpin'. The 'emulatorpin' entry puts the emulator tasks on other CPUs and off the VM CPUs. I then assigned the isolated CPUs to my VM and added the 'emulatorpin': <cputune> <vcpupin vcpu='0' cpuset='2'/> <vcpupin vcpu='1' cpuset='3'/> <vcpupin vcpu='2' cpuset='6'/> <vcpupin vcpu='3' cpuset='7'/> <emulatorpin cpuset='0,4'/> </cputune> What ends up happening is that the 4 logical CPUs (2,3,6,7) are not used by Linux but are available to assign to VMs. I then assigned them to the VM and pinned emulator tasks to CPUs (0,4). This is the first CPU pair. Linux tends to favor the low numbered CPUs. Make your CPU assignments in the VM editor and then edit the xml and add the emulatorpin assignment. Don't change any other CPU settings in the xml. I've seen recommendations to change the topology: <cpu mode='host-passthrough'> <topology sockets='1' cores='2' threads='2'/> </cpu> Don't make any changes to this setting. The VM manager does it appropriately. There is no advantage in making changes and it can cause problems like a VM that crashes. This has greatly improved the performance of my Windows 7 Media Center VM serving Media Center Extenders. I am not a KVM expert and this may not be the best way to do this, but in reading some forum posts and searching the internet, this is the best I've found so far. I would like to see LT offer some performance tuning settings in the VM manager that would help with these settings to improve performance in a VM without all the gyrations I've done here to get the performance I need in my VM. They could at least offer some 'emulatorpin' settings. Note: I still see confusion about physical CPUs, vcpus, and hyperthreaded pairs. CPU pairs like 3,7 are two threads that share a core. It is not a core with a hyperthread. When isolating and assigning CPUs to a VM, do it in pairs. Don't isolate and assign one (3) and not its pair (7) unless you don't assign 7 to any other VM. This is not going to give you what you want. vcpus are relative to the VM only. You don't isolate vcpus, you isolate physical CPUs that are then assigned to VM vcpus. Edited September 2, 2017 by dlandon 5 1 Quote Link to comment
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.