Re: [PATCH] faster yv12 to yuy2 color conversion
Roland Scheidegger <[email protected]>
| Newsgroups | gmane.comp.video.xine.devel |
|---|---|
| Message-ID | <[email protected]> |
Am 12.04.2012 14:10, schrieb Petri Hintukainen: > On ke, 2012-04-11 at 03:59 +0200, Roland Scheidegger wrote: >> Am 10.04.2012 15:57, schrieb Petri Hintukainen: >>> Could the interlaced loops (y) be combined ? It could make the code >>> simpler. It could also reduce cache misses and even improve streaming >>> stores. The loop is already over 200 bytes long. >>> >>> Have you tried if using prefetch for YUV planes has any effect ? >> >> Hmm I ran some numbers with somewhat interesting results. >> (I did not do that on a per-loop base but per-line base, mostly because > > Yes, that's what I meant with (y). > >> it is probably better to assume cpus don't have at least 4 (might even >> need more actually) write buffers - I'm not even sure all have 2 which >> the current version needs. There's also lots of arguments to pass around >> otherwise.) >> >> The K8 is rather indifferent to both of these, performance barely moves >> at all (note unfortunately adding prefetch can't be done in a optimal >> way neither, it's either tons of unnecessary ones (which shouldn't hurt >> much) or another branch in the innermost loop because for luma values >> only one prefetch per 8 loop iteration is useful and for chroma values >> it's only one per 16 loop iterations even due to 64byte line size plus >> it's also ugly due to the argument swapping in the assembly). If >> anything both of these changes might have made it very slightly faster >> but the difference was really too small to tell. >> >> On a Core2-class chip however things are a bit different: adding >> prefetch still didn't do much. However, doing both odd/even lines at >> once gets a noticeable boost (10% or so), adding prefetch on top of that >> does nothing at all. >> >> I believe these results can easily be explained by the much more >> sophisticated hw prefetcher of the core2, which you cannot beat for >> consecutive accesses. The K8 can't prefetch that deeply but memory >> latency is much lower, which probably means the hw prefetcher does its >> job (hence sw prefetch doesn't help much) but the occasional miss at >> line start doesn't hurt much neither really. >> >> So I guess at least for the mmxext case doing both loops at once is >> better (I'm a bit hesitant of doing that for the mmx case the cpus there >> could have vastly different performance characteristics - I also tend to >> think prefetch would help older cpus more as those had pretty dumb if >> any hw prefetchers). >> >> I tried interleaving the code and if anything it got slightly slower >> (maybe too many loads without arithmetic at beginning dunno it could >> have been just statistical noise). In any case I tried a quick hacked >> sse2 version and performance still was exactly the same even on a core2 >> (which has 128bit simd units and hence really could be twice as fast if >> arithmetic throughput were limiting performance). So this code really >> has reached the limits wrt memory subsystem (it might be different on >> nehalem) and trying to optimize for higher arithmetic throughput seems >> to do nothing but make the code unreadable (well on the mmxext case at >> least the mmx one probably does have some potential but I don't really >> care about that nor do I have a cpu where I could really measure it). On >> Nehalem or other similarly fast cpus certainly adding a sse2 version >> would have priority over such hacks too (maybe it would not be totally >> limited by memory system with mmx but I bet with sse2 it would be back >> instantly to being 100% limited by memory - of course nehalem most >> likely also means large caches so exploring options of not always using >> streaming stores depending on video and cache size might be worthwile >> too there). > > With Core i3 I get ~25% speedup by simply converting your mmxext version > to use sse2 regs. I can also test on Atom N550 to see if there is any > difference between mmxext and sse2. Ah interesting. Memory subsystem finally catching up a bit :-). Atoms of course don't have a terribly fast memory system, though given the code isn't optimized for the in-order nature of the cpu might still help a bit (though at least all the simple arithmetic simd int instructions have latency of 1 only so it shouldn't run that badly neither). > > It seems streaming store might be useful with i3 (3MB L2 cache) too. > Converting SD video is slightly faster with streaming stores. But I > didn't test if it slows down overall process with deinterlacing > immediately after conversion... Interesting. Deinterlacer could indeed be slower afterwards if it fits into cache, though some (like greedy2frame) require more than one frame hence even more cache is probably needed (though at least for sd there still might be enough). > >> The generated code actually looks quite bad at least on 32bit, there's >> lots of moves (I tried improving that by using memory operands which >> lets gcc use more complex address operands, but it does only really do >> something for the first asm block not the other ones hence I moved some >> stuff slightly which cuts down innermost loop instructions quite a bit, >> not that it does anything for performance - using just one asm block >> would generate even slightly better code on 64bit but not compile on >> 32bit unfortunately...). >> >> I've also fixed the trivial bug in the progressive assembly code... >> >> In any case I'm done with this code for now. > > Thanks! > > I don't have much time this week, but I'll try to look at the > deinterlacing stuff more at next week. > > Have you tried what kind of results you get if you skip yv12->yuy2 > conversion (tvtime with cheap_mode=1) ? Well cheap_mode doesn't do full_frame mode so I'm not terribly interested in it. Greedy2frame isn't quite a good match for this in any case since the different weighting used for for chroma/luma values really doesn't make sense when using cheap_mode. > > Some simple deinterlacing algorithms may be also easy to convert to work > directly with yv12 ? "simple" isn't really that interesting :-). But for the weave-or-bob ones doing yv12 conversion in deinterlacer could really give better results too (aside from needing to read less memory) as the deinterlace algorithm can be changed from interlaced to progressive (though it might get a bit cpu intensive - not only need to do both methods (unless using block-based branches) but also need to do it twice for full frame rate). > > I'm trying to add some SSE2 code and threading to deinterlacers. I'm > pretty sure threading helps with multi core cpus, currently video > decoder and deinterlacer run in the same thread. Well h.264 can run in different threads (ok that's a lie it's broken in xine due to broken initialization but fixing that sort of works though decoding breaks apart pretty badly if the combined cpu load for 2 cpus reaches 150% or so). In any case might help very nicely, I'm curious how you solve the alignment issues with sse2... Roland ------------------------------------------------------------------------------ For Developers, A Lot Can Happen In A Second. Boundary is the first to Know...and Tell You. Monitor Your Applications in Ultra-Fine Resolution. Try it FREE! http://p.sf.net/sfu/Boundary-d2dvs2