I'm wondering in what scenarios is there value in setting the CPU affinity.
Generally, CPU affinity is used for process isolation or to reduce contention for resources. High-frequency trading is the application in which I use CPU sets and CPU shielding, but I've also seen applications in scientific/computational computing (HPC), realtime applications and e-commerce. Professional audio applications are another common example that requires realtime kernels and CPU affinity sets.
At the basic level, the taskset command is used to assign affinities.
This is a tutorial for creating groups of CPUs for specific applications/processes using cset, which is a little more organized than taskset. https://rt.wiki.kernel.org/index.php/Cpuset_management_utility/tutorial
CPU affinity matters in two scenarios: the most common is simply when your workload benefits considerably from CPU caching and there's enough resource contention to cause jobs to be moved across cores or CPUs, which causes each CPU to need to invalidate its cache and rebuild it. A more extreme version of this happens on systems with a non-uniform memory architecture (NUMA) where banks of RAM are physically connected to a specific CPU, which will always have faster access to that memory.
In general, for this sort of problem you really want to monitor it first to see if it's an issue - there's no point in fiddling with CPU scheduling if your app is I/O bound - which can be as simple as running top and watching the CPU column to see if jobs are bouncing around. There's also some basic system configuration work making sure that any block of memory which you access heavily can actually fit on the amount attached to any one CPU.
For testing, the easiest way to set affinity is using the taskset utility. You might also want to look at libnuma as numactl provides independent controls for both CPU and memory allocation and, more importantly, the libnuma library provides a programatic way for your applications to request favorable allocations: for example you might want to request that a group of threads which share certain data structures be allocated to other cores on the same CPU rather than having to take the performance hit of going over an interconnect.