There is no good reason to flip the flag dynamically at runtime and apps just don't do that, so flushing the pipeline should be perfectly fine, even in an implementation of the clip control extension.
On a modern x86 cpu the ‘xchg’ instruction performs a swap and can do so entirely in the front-end via register renaming. It doesn’t even require a micro-op.
This ‘trick’ actually requires executing micro-ops and creates an unnecessary data dependency (which is actually worse than the micro-ops themselves).
Better to just use more variables and let the register allocator in the compiler decide what to do. If it’s a loop then unrolling it once could remove the need for any swapping at all, for example.
> On a modern x86 cpu the ‘xchg’ instruction performs a swap and can do so entirely in the front-end via register renaming. It doesn’t even require a micro-op.
This is only true for AMD cpus, on Intel xchg is 3 uops. Still better than the xor trick, though.
this isn't going to be any better than just loading from the two buffers into registers then storing the other way around, like:
a = load(ap)
b = load(bp)
store(ap, b)
store(bp, a)
ap += step; bp += step;
any instructions to "do the swap" are a waste because generally load-store are separate instructions in SIMD instruction sets (and even if that wasn't the case, that's how they would get executed anyway)
if you want to avoid polluting the cache there are SSE instructions for loading without caching, which might be worthwhile
edit: this might be useful in a SIMD context where you need to swap two registers, where the cost of using another register is higher than the cost of the 3 arithmetic instructions. i could totally imagine that happening, but it's nothing to do with caches or memory
> What if you want to swap two large memory blocks?
In theory, maybe.
But if that happens in your application and is performance critical, you probably should change it such that you're swapping pointers to them instead...
There are very real cases where you may want to swap around actual memory though. Gabage collectors do quite a lot of this type of large memory exhanges.
If you generate the rays the linear way instead, you don't even need any correction.
Generate two points which represent the left and right edges of the screen - you'd put them in at say 45 degrees left and right of the forward vector of the player. Then to generate the direction vector for each column of the screen, just interpolate linearly between those two points, and find the vector from the player to that intermediate point.
The venerable lodev tutorial uses this method, which I also used for most of my engines. I learned an interesting tidbit while comparing the two methods though:
The old-school original methods used pretty small cos/sin/atan lookup tables to do the ray and then the correction calc. Using the linear method you end up with a couple divisions per ray that aren't there in the lookup method. Divisions were (and are, depending on the platform) pretty slow. Linear method still works with lookup tables but they're relatively huge.
Also IIRC With the linear method door-indents need a workaround.