Relatedly, it'd be cool if one of the AMD people involved in the OpenCL work (which was committed at the same time) could do a writeup of those optimizations.
6,761 karma · joined July 15, 2008
My blog: http://x264dev.multimedia.cx/
My email: jason@x264.com
Relatedly, it'd be cool if one of the AMD people involved in the OpenCL work (which was committed at the same time) could do a writeup of those optimizations.
Floating point bitwise operations exist too: xorps, andps, and so on.
The problem has many parts:
1. Autovectorization in general is just extremely difficult and even trivial code segments often get compiled very badly. It feels like the compiler is trying to fit the code into a few autovectorization special cases -- for example, a 16x16->16 multiply gets compiled into a 16x16->32 multiply, and then it laboriously extracts the 16 bits, probably because nobody wrote code to explicitly handle the former variant. A good autovectorizer would have to have a vast array of these sort of things to "know what to do" in a particular case, I'd imagine.
A lot of autovectorization resources seem to be tuned towards floating point math (which typically doesn't need the same sort of tricks), which probably exacerbates the problem in x264's case.
2. The compiler doesn't know enough. It can't guarantee alignment, it doesn't know about the possible ranges of the input values or the relationship among them, it doesn't know the things the programmer knows.
3. SIMD algorithms are often wildly different from the original C. Much of the process of writing assembly is figuring out how to restructure, reorder, and transform algorithms to be more suitable for SIMD. The compiler can't really realistically do this; its job is to translate your C operations into machine operations, not rewrite your algorithm.
Part of this problem is that C is just not a great vector math language, but part of it is also that the optimal algorithm structure will depend on the capabilities of your SIMD instructions and their performance. For example, when the pmaddubsw instruction is available, it's faster to do x264's SATD using a horizontal transform first, but if not, it's faster to do it with a vertical transform first. The Atom CPU has pmaddubsw, but only has a 64-bit multiplier, making it too slow to utilize the horizontal version (so it gets the vertical version instead).
You can definitely finagle code into getting hit by the autovectorizer, especially with Intel's compiler, but it takes a lot of futzing to make it happy, and even when it is happy, it can be many times slower than proper assembly. Of course, it's not useless -- it can get you some relatively free performance improvements without writing actual SIMD code. But it's not a replacement.
The pain of not having a proper macro assembler in C intrinsics is orders of magnitude worse than having to do my own register allocation in yasm, so for now, yasm is the lesser of two evils.
In return, you are stuck with an extremely ugly syntax and a much less functional preprocessor, with the added bonus of a compiler that mangles your code.
sde -- ./myprogram myargs
instead of
./myprogram myargs
There's also probably a decent number of people at this point who have prerelease CPUs; they tend to breed quite explosively in the month or two before the official release.
If you want to test without a physical Haswell, the Intel Software Development Emulator should work okay, albeit somewhat slowly. I'd post overall numbers for real Haswells, but Intel has apparently said we can't do that yet.
Regarding FMA, FMA3/4 are floating point only. Since x264 has just one floating point assembly function, only two FMA3/FMA4 instructions get used in all of x264 (not counting duplicates from different-architecture versions of the function). An FMA4 version has been included for a while; the new AVX2 version does include FMA3, but of course that won't run on AMD CPUs (yet).
XOP had some integer FMA instructions, but I generally didn't find them that useful (there's a few places I found they could be slotted in, though).
Pixiv vs. DeviantArt
Mixi vs. Facebook
Nico Nico Douga vs. Youtube
China is an even more extreme case, though that also has problems of corruption, legal wrangling, censorship, and so on.
For some reason, the "testimonials from random Japanese people" idea seems rather unsettling to me. It makes it feel exoticized, touristy, and fake.
High-res Dirac video encoding is definitely possible in real-time, you just need a very optimized encoder, which doesn't really exist. Dirac's main speed cost comes from the overlapped-block motion compensation, not the transform.
No matter what happened here, this entire concept is horribly, horribly wrong. It's blaming the victim -- saying that it's somehow her fault for "causing" the stalker to do something... as opposed to the stalker's fault, for stalking.
It's not perfect, but for ANY site of sufficient size with unmoderated user content, this problem eventually has to be dealt with. Threatening to ban the victims is not a solution.
Kickstarter earns 5% from every single successful project: they can afford putting some effort into moderation and protecting their customers.
"Binning parts" means they're either actually hardware-disabling ("diking out") the extra core, or the extra core was bad to begin with (making use of otherwise bad chips).
If those images are real, both cores are definitely on the chip, but whether one is hardware-disabled or not is not certain.
I haven't found this to be true in my (limited) experience. In writing sliced-threading support for x264, threading issues took up only a small percentage of my time. Admittedly, this is a rather simple application: the frame is split up into independent threads which never wait on each other, communicate asynchronously without any attempt at determinism, and all finish before the program can continue.
My experience is limited, but a generalization like "always going to be easier" seems rather at odds with reality. I have never found dealing with mutexes to be difficult in any situation. What I have found to be difficult is trying to design lock-free code, using memory barriers, and other trickiness to avoid slow locks in situations where the overhead of locking is just intolerable. This is definitely an application where things like pre-made lockless datastructures and the like come in handy.
One common example is the need to split a larger task into smaller subcomponents, but where all of the components combined need to obey some global constraints. A specific example: we're compressing a video frame, the result must fit within a certain size, and we can't parallelize over multiple frames for latency reasons. This means we need to split the frame into chunks, but somehow all the chunks have to communicate with each other in real-time, as they work, in order to ensure they obey the global constraint. Do you have a "master" thread that manages them all and makes decisions? Do you use some sort of algorithm where they act as separate agents, asking each other questions? Suddenly this is a lot more complicated than what you started with.
Another example is a search algorithm. Whether you're performing a minimax search of a game tree or simplex optimization, you're implementing algorithms that are normally not parallel. Parallelizing minimax is actually incredibly difficult and requires making a lot of hard decisions about where you branch threads, where a thread gives up, how to avoid duplication, and so forth. Fancy programming tools can give you features like thread-safe hash tables that help you, but they don't solve the actual problem. See any multithreaded chess engine for an example of this problem. Note particularly that the engines don't get perfect speedup from multithreading -- but it's NOT because of Amdahl's Law! It's because the searches between threads unavoidably duplicate at least some work.
"Moving data, operating on it" would be grossly oversimplifying real-world, complex programs like these, and there's nothing a functional language would do to "trivially parallelize" them. Dependencies in calculations are often so tangling that you cannot naively parallelize them without making dramatic, possibly sacrificial, changes.
Tools like FP can be useful, but they don't solve problems of inherent complexity. There is no silver bullet.
But parallelism is harder than that. It's an algorithm problem, a design problem, not a language or code problem. While OpenCL might be harder to write than plain C, for anything except the most embarrassingly parallel problems, that difficulty pales in comparison to making the solution parallel to begin with.
For every problem where you can simply split into masses of shared-nothing tasks, there's a dozen others where you can't. Rate-constrained video compression. Minimax AI search. Emulation. All of these can be parallelized, but it requires parallelizing the algorithm and making sacrifices that are light-years beyond what a dumb compiler that isn't even allowed to change program output (let alone rewrite half the program) could do.
Modifying an algorithm -- possibly even changing its structure entirely, changing its output, or even accepting nondeterminism -- is inherent complexity, to use the terminology of Mythical Man Month. No programming language or tool can eliminate this complexity. Good tools can make it easier to implement an algorithm efficiently, but they really can't take a complicated application and figure out how to change its design, structure, and behavior. Until we have AI-complete compilers that take program specs as "code" to be compiled, that's a human job.
We tried placing ads for ninjas, rock stars, and so on, but I discovered this was the cultural equivalent of advertising for white males who drink dry martinis. Not that white males who drink dry martinis can’t do the job, but there’s no real difference between advertising for a Ninja and throwing half your resumés away because you don’t like unlucky people. Either way, you end up with fewer resumés.”
This is so true, so important, and so many startups (and even bigger companies!) miss this. Job ads provide cues, conscious and subconscious, to the people reading them. Not everyone reading the ad is identical to the person writing it, and a badly written job ad can easily send the message "this company isn't for you" to a large number of skilled potential applicants. This applies not just to categories like gender or race, but even to personality types and personal interests. Unless you really want a company of only extroverts, for example, don't write a job ad that scares off introverts.
In the canonical example, if you constantly ask for "rock stars", you will turn off people to whom that doesn't appeal, including tons of good programmers. But it goes beyond that: don't assume that all your applicants are any particular kind of person with certain interests. A job ad should focus on what the job actually is, and things that are important to the job.
The best programmers often have a lot of choice in where they work, and as many HNers know from experience, if they see a job ad that turns them off in some fashion, they will probably not even bother reading further: they know they have better options, so yours probably isn't worth their time. If the vast majority of skilled programmers skip over your resume, it's no wonder you only receive resumes from unqualified applicants.
In short, when writing a job ad, you need to think from the perspective of people applying. Use your empathy, put yourself in their shoes, rather than just writing what you think looks cool.
Now I'm not sure how much this'd actually affect. The autovectorization in Intel's compiler is weak and, at least on Win64, sse2 is allowed in normal code without CPU dispatching. It does affect library functions like math and memcpy, but that'll only matter if your program spends a ton of time in them.
Additionally, x264 should probably categorized under "no significant floating point calculations".