You can visually inspect the diffusion of different operations using an avalanche diagram.
I've generated the avalanche diagrams of these operations, the sizes I used for $a$ and $b$ are 64 bits. The result is also a 64-bit variable.
The tool I use generates the diagrams for all bit changes instead of just $a$, but it should still be informative.
Diffusion of $a \oplus b$
As you guessed; with plain XOR, the output bit $c_n$ is only affected by input bits $a_n$ and $b_n$. Here's what that looks like.
![Avalanche diagram of XOR](https://i.stack.imgur.com/W1N8g.png)
Diffusion of $a + b$
A slight improvement is addition. You can see that instead of each bit only affecting itself, there is now a very slight diffusion around the bits.
![Avalanche diagram of addition](https://i.stack.imgur.com/EZfMo.png)
Diffusion of $a \cdot b$
Multiplication provides a massive improvement. But multiplication only diffuses changes in one direction. And depending on the processor you are targeting, multiplications might be expensive or not constant time.
![Avalanche diagram of multiplication](https://i.stack.imgur.com/9unk2.png)
Diffusion by repeating simple mixers
If you take a bunch of invertible operations that somewhat diffuse the changes, and repetitively perform them, you can get much better results.
Below is an example with just XOR-shifts and add-shifts.
![Avalanche diagram of repetition](https://i.stack.imgur.com/ZVitC.png)
Here's the operations that are being performed. As you can see, individually none of those diffuse that much, but if you repeat them enough, the mixing is much better.
for (size_t i = 0; i < 4; i++) {
// Mix a
a ^= a >> 7;
a += a << 13;
a ^= a >> 9;
// Mix b
b ^= b >> 7;
b += b << 13;
b ^= b >> 9;
// Shift a and b into each other
u64 a_old = a;
u64 b_old = b;
a = (a_old << 8) | ((b_old >> 56) & 0xFF);
b = (b_old << 8) | ((a_old >> 56) & 0xFF);
}
u64 c = a ^ b;