Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
Media Programming Hardware

FFmpeg Devs Boast of Up To 94x Performance Boost After Implementing Handwritten AVX-512 Assembly Code (tomshardware.com) 78

Anton Shilov reports via Tom's Hardware: FFmpeg is an open-source video decoding project developed by volunteers who contribute to its codebase, fix bugs, and add new features. The project is led by a small group of core developers and maintainers who oversee its direction and ensure that contributions meet certain standards. They coordinate the project's development and release cycles, merging contributions from other developers. This group of developers tried to implement a handwritten AVX512 assembly code path, something that has rarely been done before, at least not in the video industry.

The developers have created an optimized code path using the AVX-512 instruction set to accelerate specific functions within the FFmpeg multimedia processing library. By leveraging AVX-512, they were able to achieve significant performance improvements -- from three to 94 times faster -- compared to standard implementations. AVX-512 enables processing large chunks of data in parallel using 512-bit registers, which can handle up to 16 single-precision FLOPS or 8 double-precision FLOPS in one operation. This optimization is ideal for compute-heavy tasks in general, but in the case of video and image processing in particular.

The benchmarking results show that the new handwritten AVX-512 code path performs considerably faster than other implementations, including baseline C code and lower SIMD instruction sets like AVX2 and SSSE3. In some cases, the revamped AVX-512 codepath achieves a speedup of nearly 94 times over the baseline, highlighting the efficiency of hand-optimized assembly code for AVX-512.

FFmpeg Devs Boast of Up To 94x Performance Boost After Implementing Handwritten AVX-512 Assembly Code

Comments Filter:
  • Neat... But, (Score:5, Insightful)

    by Valgrus Thunderaxe ( 8769977 ) on Monday November 04, 2024 @05:55PM (#64919749)
    With a 94x improvement, someone needs to fix their compiler.
  • I hope it's a real world benchmark not some contrived situation and propaganda from Intel.

  • by dfghjk ( 711126 ) on Monday November 04, 2024 @06:07PM (#64919771)

    Why didn't they just ask ChatGPT to rewrite it? Handwritten? Haven't we been told there's no reason for that?

  • by ip_freely_2000 ( 577249 ) on Monday November 04, 2024 @06:09PM (#64919777)
    I've had 90%+ optimizations on certain data processing functions by hand coding and tuning instead of depending on libraries and other 'productivity' tools. In my coding life (which is long but fortunately very nearly over) we've added layer upon layer of complexity which is sometimes not necessary.
    • by backslashdot ( 95548 ) on Monday November 04, 2024 @06:18PM (#64919791)

      I stopped coding/optimizing in assembly over 20 years ago, and then only utilized knowledge of it for debugging, cybersecurity, or fun purposes for a few years. Nowadays I have zero use for it other than getting super annoyed that people don't know it.

      • by dsgrntlxmply ( 610492 ) on Monday November 04, 2024 @07:37PM (#64919985)

        Hey punk, get off my ROM!

        My last significant use of assembly was late 80s / early 90s. Working on embedded systems with 8-bit microprocessors, tiny boot ROM capacity, and rudimentary or no compiler, there was no choice. Around 2017, I had to take a deep dive into GCC compiled ARM code to characterize an obscure but dramatic failure in a specific embedded situation. This turned out to be incorrect code generated by GCC. Once characterized, it was not difficult to work around, but it required machine level knowledge to locate.

    • by Tony Isaac ( 1301187 ) on Monday November 04, 2024 @06:21PM (#64919801) Homepage

      That, and programmers often use boneheaded algorithms because they don't know any better.

      Remember Bubble Sort? If you tried to build the most inefficient algorithm possible, it's hard to imagine one that would beat Bubble Sort. And yet for years, every computer programming textbook taught this algorithm that's useful for basically nothing, and isn't even intuitive. Students normally react with "How does that even work???" But you know that algorithm made its way into more than a few production systems.

      Software optimization employs some very specific techniques. Notably, using some kind of profiler to identify where your bottlenecks are, and looking for ways to reduce execution or loop counts, or ways to reduce the time spent in each iteration. There's a whole lot of software, including decoding algorithms, that never went through any kind of proper optimization analysis.

      I agree, it's not surprising to find ways to increase performance by 90+%, regardless of the language chosen.

      • by Entrope ( 68843 )

        If you tried to build the most inefficient algorithm possible, it's hard to imagine one that would beat Bubble Sort.

        Challenge accepted [wikipedia.org].

        • Funny! Well, since this sort compares its slowness to Bubble Sort, it would seem that Bubble Sort might still get 2nd place for slowest!

        • by vux984 ( 928602 )

          Bah - I like random sort, which is essentially:

          swap two elements at random
          check if the list is sorted now
          repeat if the list is not sorted

          Given enough time, it will sort the list, quite by accident. ;)

          • If truly random, it's not guaranteed to ever finish.
            Or if your random number generator is broken (worst case it always returns the same number), then it certainly won't finish.

      • by ShanghaiBill ( 739463 ) on Monday November 04, 2024 @06:54PM (#64919895)

        If you tried to build the most inefficient algorithm possible, it's hard to imagine one that would beat Bubble Sort.

        Then you lack imagination. Bubble sort is O(n^2). There are O(n^3) sorting algorithms. Here's an O(n!) sort:

        1. Shuffle data randomly
        2. Test if it is sorted. If yes, you're done, else go to 1.

        And yet for years, every computer programming textbook taught this algorithm that's useful for basically nothing

        Bubble sort is useful for very small datasets, like 10 or so, and constrained memory or cache capacity.

        But bubble sort is most taught as an example of a naive implementation leading to poor performance.

        isn't even intuitive. Students normally react with "How does that even work???"

        It's obvious why Bubble sort works. It is way easier to understand than Quicksort.

      • Remember Bubble Sort? If you tried to build the most inefficient algorithm possible, it's hard to imagine one that would beat Bubble Sort. And yet for years, every computer programming textbook taught this algorithm that's useful for basically nothing, and isn't even intuitive. Students normally react with "How does that even work???" But you know that algorithm made its way into more than a few production systems.

        Bubble Sort sorts an already sorted list in O(n) time. Try doing the same thing with Merge Sor

      • Remember Bubble Sort? If you tried to build the most inefficient algorithm possible, it's hard to imagine one that would beat Bubble Sort

        Bubble sort is faster than Quicksort for less than 8 items. That sounds like nothing, but then you realize many if not most sorts done probably have fewer than 8 items.

      • And yet for years, every computer programming textbook taught this algorithm that's useful for basically nothing, and isn't even intuitive.

        You didn't pay any attention in class. Bubble sort is held up in virtually every textbook as an example of something that does the base line job in an inefficient way. It is literally taught as an example of not being useful.

        That said I think your assertion that it isn't intuitive is quite silly. It's probably the most intuitive algorithm that is. Is current value bigger than next value in array? If so, switch, repeat, done. There is literally nothing more intuitive than comparing two numbers and just movin

        • Perhaps where and when you went to school, they taught bubble sort as an example of inefficient programming. But maybe the 1970s were before your time. In those days, it was presented simply an example of how to sort.

        • Yeah, I've been thinking that if you assign an inexperienced programmer, like a student, to sort a list without any training, you're probably going to get something like bubblesort.

      • by AvitarX ( 172628 )

        I learned bubble sort as a functional example of a while loop.

        It is a super easy to understand program that does something useful and demonstrates some basic functions. We were also told it was pretty useless in real life.

        I don't know why you think it's hard to understand, except for maybe that it's pretty much the first thing taught. It was meant to be hardish to understand but understandable at the point it was taught (like first week or so).

    • Optimizing in assembly used to be a routine thing. I guess it went away because: 1. Takes forever. 2. Only very smart people can do it. 3. Idiot managers only want shipped product, today!

      I think #2 is the real bottleneck. Geniuses have lots of options, working for idiots is a shitty option.

      • I wonder how much faster it will be when it's written in rust?

        • Haha I came her to comment almost the same thing. Can't tell if you are being sarcastic though. But I sure was going to be.

          The masturbating security monkeys sure seem to think Rust is hot shit but I want REAL WORLD examples dammit. If I was a billionaire I would be paying top programmers to battle head to head, and benchmark both the code, and TIME TO WRITE the code, of C vs Rust

          • When does the competition end? You should be counting for vulnerabilities in the initial product and also over time as it gets updated with new features and existing bugs get fixed buy developers who didnâ(TM)t have anything to do with the original code.

            • Does that include the few minutes it takes to write memory safe libraries in C to wrap the most common functions?

              • Sounds like you've fixed the problem already! There will be no more use-after-free, uninitialised memory, double-free, or buffer overflows ever again, all it takes is a few minutes to fix it all.

      • Well, maintenance nightmare aside, it's actually pretty hard to get performance out of handwritten assembly on x86. It's not worth it. I've seen the compiler spit out utter garbage but it still runs at roughly the same speed of handwritten assembly, just because of the amazing pipeline process the CPU has. The main benefit you'd get is a smaller binary file. The SIMD instructions are the outlier, where compiler support might not be good enough, where the instructions are difficult to generate for.

        • The thing that really slows things down in modern assembly isn't "number of instructions" (as you mentioned).

          The things you really want to look at are "number of memory accesses" or "number of missed branch predictions." Aligning cache accesses correctly can also be a big win.
          • ...you missed "length of dependency chains"

            you can only retire 1 op per cycle if each of your ops depends on the result of the previous op .. you end up limited to the latency of your longest dependency chain even in the optimal case

            the real problem with compilers is that you get different performance depending on optimization settings, but not all optimizations are actually safe, and the benchmark will always be with the best set of all of that but probably when you grab the source and use it in your o
            • Not entirely true.

              Fused Multiply and Add is technically a multiple operations executed in a single cycle.

              But otherwise, agreed
    • Mostly I have used assembler to do stuff needed in a system, stuff that a general purpose library does you on a full operating system. But in an embedded system you are the full operating system, and the RTOSs out there don't give you system startup code and the like. For instance, cache invalidation instructions, interrupt/exception handlers, memory barriers, context switching, etc. Other times you _know_ the code is very slow and can be sped up, and can't easily be sped up with pure standard C code.

      In

    • I think the bigger deal is that an open source project pulled this off.

      What makes open source work is you can use all those libraries to put together incredibly useful and complex software but the downside is you can't just throw a few million dollars at paying some guy with a masters or a PhD in mathematics and computer science to do cool shit for you.

      Getting these kind of optimizations done in an open source framework is super cool.
    • 90% is a good start. But these guys got 9400%. Two factors of magnitude is the difference between get a bruise and sending your head across a football field.

      Yeah I know, you meant 90x. Still it's a pretty major improvement for a tool that lots of people use, unlike your code...

  • by Xylantiel ( 177496 ) on Monday November 04, 2024 @06:19PM (#64919795)
    I fiddled with this a bit once and it seemed that not all chips implemented "actual" AVX-512. i.e. some chips just support the instructions, they don't actually have the hardware to do all those operation in parallel. Maybe that is discussed more in the article.
    • Yes. Zen4 and especially Zen5 will benefit greatly. Intel dumped AVX512 support on their desktop CPUs with Alder Lake, so unless you're using a Xeon or something you will won't be able to use that codepath.

  • Due to the nature of assembler, that code will be bound to one CPU architecture.

    Won't help those of us on ARM or Apple silicon.

    I suppose we could offload video over the network to an x86 architecture box, but that'll eat up some of that 94x.

    Wonder what Windows and MacOS emulators make of raw machine code?

    • I have an acquaintance that works for one of the FAANG companies. The focus of their team is to hand write assembly for performance critical operations across the company. They do this for multiple chip architectures.

      Your phone or PC might well have some of that code in it.

    • AVX512 instructions are specific to x86. If you want the same sort of accelerations in ARM (including Apple M series processors) you need to use something like Scalable Vector Extension (SVE) or Scalable Vector Extension 2 (SVE2) which is written for the ARM architecture family.
      • Apple doesn't yet support SVE2.

      • For video transcoding, you wouldn’t do it this way on Apple Silicon. You’d call the OS video library which would automatically invoke the video ASIC components of the CPU.

        • For video transcoding, you wouldn’t do it this way on Apple Silicon. You’d call the OS video library which would automatically invoke the video ASIC components of the CPU.

          True, you would use the OS video library on an x86 platform, potentially incorporating the faster handwritten AVX-512 code.
          If anyone can improve the speed of the Apple Silicon code libraries by using handwritten assembler code then they're free to submit it to Apple.
          It's my guess is that there wouldn't be that much additional improvement in performance as was wrung out of the AVX-512 code.

    • Architecturally, it's not a problem. You just encapsulate the assembly in a function, and use polymorphism, based on whether the CPU feature is available. For the platforms that don't have the ability, they will just run slower. Apparently 94x slower or something.
      • by godrik ( 1287354 )

        IIRC ffmpeg does that at load time. When the library load, it checks your processor architecture and loads the right library to provide the implementation of these functions. So really it is done at the level of the symbol table. That gives you a no performance hit for these type of things.

        Many BLAS libraries do things of that sort as well. (Intel MKL definitely does that.)

    • by edwdig ( 47888 )

      AVX is a set of CPU instructions designed for operating on multiple values with one instruction. If you go anywhere near this sort of stuff, you're already tying yourself to a specific type of CPU.

      This is the kind of optimization you do for stuff that's really CPU intense, like video codecs. This is where you really want efficient code, not portable code.

      • by jddj ( 1085169 )

        It's funny. People posting all these replies seem to think I wasn't disassembling 6502 games for my Atari 400 in the 1980s so I could bust the copy protection and move them from tape to disk.

        I'm well aware of what assembler is, how it works, what it does, and the advantages it confers, as well as the complexity it unfolds that higher-level languages and acceleration APIs do a good job of hiding. I haven't taken a close look at instruction sets recently (though I used to know the Z-80 set by heart).

        I'm just

  • by Anonymous Coward

    A while back, I was working at a place that did video production. They had these expensive, barely working video appliances that the license fees were just plain extortion, and the support was often, "buy our newer model, and we might fix that". I took the physical appliance, removed the disk with the vendor OS and set it aside if need be, installed Linux and used ffmpeg for everything that appliance did. It worked perfectly, and did what we needed it to do, and might as use the Supermicro hardware that

  • by msauve ( 701917 ) on Monday November 04, 2024 @07:11PM (#64919933)
    Since the summary couldn't be bothered, AVX-512 is an instruction set extension for X86 processors.
  • Hand coding can drastically improve performance if you know what you're doing and the compiler is doing a poor job. That being said, Intel is deprecating its AVX-512 support since it wasn't worth the silicon. AMD on the other hand did a much better job of it.
  • by godrik ( 1287354 ) on Monday November 04, 2024 @08:16PM (#64920053)

    AVX-512 should not be able to give you a 94x speedup. What are they comparing against, -O1?
    Using AVX-512 should make you go from processing 32bit at a time to processing 512 bits at a time. That should give you at least a 16x speedup.
    Depending on architectures, you can get up to 3 ports of the processor filled with instructors, but that only brings it to 48x speedup. To get to get to a 94x speedup you'd need twice that. So not only you fill all three ports which the baseline couldn't do, but you also send these instruction twice as often with some unroll or something like that.
    (Though you never actually get a 16x speedup on a vector port because in practice most processors have to downclock to have enough power to feed the 512 bit vector units. )
    That also assume that the calculations are entirely instruction bound and not IO bound (including memory bound).

    I do this shit for a living. I highly doubt the 94x speedup of avx-512 against a reasonable compiler with the appropriate compilation flag on a reasonable C implementation of the code. It is not that hard to write code that compile decently well. Even adding a littlebit of unroll and compiler instrinsic in important loops can give you significant performance improvement over -O3.
    Getting a 94x improvement over decent code using handwritten assembly should not be possible. The last time I saw results like that was during the Cell era when compilers didn't know anything about the SPE except the ISA. I have to guess that the baseline here is something unreasonable like "gold standard compiled -O1".

    Do someone has the paper that is being presented here?

    (Though kudos for handwriting writing AVX-512 production code. That's not easy.)

    • by edwdig ( 47888 )

      I would imagine there's also improvements like better memory alignment to avoid cache misses. Maybe more inlining of code, avoiding function calls and branching.

      They're probably doing broader optimizations than you're thinking.

      • by godrik ( 1287354 )

        all of that is totally doable in regular C code. You don't need to handwrite assembly to get there. And pretty much all of that is a generic optimization so you would want that to be part of your baseline.

      • function calls under standard abis are costly and always were, but modern compilers seem to gladly inline anything you tell them to (even languages like c#)

        When to inline is not a solved problem and we know its not a solved problem because compilers never do the opposite, they never find expressions the programmer repeated many times and turn that expression into a function. Where would you even begin with trying to automate such a thing fruitfully? We dont know the science.
  • That assembly language, and an experienced assembly language programing staff, would be more efficient than... anything else. Time and budget get hammered, but absolutely nothing beats the efficiency. Nothing.
  • If you click through to the raw benchmark data youâ(TM)ll see that the âoe94xâ is compared to a scalar code path that is hardly used. The speed up compared to the avx2 code path which what most users have been using for years is between 1.2x-2x.
  • When looking at all the coding that AI is helping with, I wonder more whether use of inefficient generalised libraries should instead become targets for some custom Assembly to replace oft used libraries and AI should be helping with that specifically... is this a common use case already, IANAD (I'm not a developer).

"It's like deja vu all over again." -- Yogi Berra

Working...