HN user

tmurray

421 karma
Posts0
Comments94
View on HN
No posts found.

they're not a userspace construct in any meaningful way. libutils/Thread (capital-T Thread) is a thin wrapper around pthread_t, and most Android code uses pthread_t directly. what this hit is probably a bug related to timerslack_ns--there's some code to tweak timerslack values on a per-thread basis instead of a per-process basis even though audio should never be coming from processes low enough on the importance list to get a high timerslack value--but L bugs fixed in M are before my time.

GPUs don't have a page fault handler; when there's a page fault, it's an unrecoverable crash. Accordingly, zero-on-allocate (or potentially zero-on-free, but that makes assumptions about startup and teardown that may not be true) is the only way to do it.

X1 is actually the 64-bit ARM CPU configuration (Cortex A53 + Cortex A57), not Denver. K1, the predecessor of X1, comes in two flavors: 32-bit 4xCortex A15 and 64-bit 2xDenver. TK1 is 32-bit, Nexus 9 is 64-bit (and is the only device I know of with Denver).

I actually read IJ on a Kindle and found it significantly easier for the most part than reading it in print because of links to endnotes, which removed the requirement to keep two sets of bookmarks (if you haven't read it, some endnotes in IJ are a sentence are two, some are 40 pages). There were some occasional issues with going back to the main text (IIRC the back button's stack wasn't saved across sleep), but overall it was much better for me.

But no, I'd never read a textbook on a Kindle. Can't flip around.

https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Function-Attrib... and http://pasky.or.cz/dev/glibc/ifunc.c

look up the target attribute and the ifunc attribute--it's basically a way to compile multiple versions of a function for different targets in a single source file and then use the dynamic linker to determine which one to resolve at runtime. obvious use is for things like optimized memcpy implementations.

How GPUs Work 12 years ago

but that's GLES 2.0, which is significantly less flexible than the kinds of GPUs we're discussing here and is not even in the same ballpark as a CPU (and almost certainly significantly less strict in terms of floating point precision than a GLES 3 device).

How GPUs Work 12 years ago

disclaimer: I work in this space and have done so for a while, including previously on CUDA and on Titan.

GPUs for general purpose computation were never 100x faster than CPUs like people claimed in 2008 or so. They're just not. That was basically NV marketing mixed with a lot of people publishing some pretty bad early work on GPUs.

Lots of early papers that fanned GPU hype followed the same basic form: "We have this standard algorithm, we tested it on a single CPU core with minimal optimizations and no SIMD (or maybe some terrible MATLAB code with zero optimization), we tested a heavily optimized GPU version, and look the GPU version is faster! By the way, we didn't port any of those optimizations back to the CPU version or measure PCIe transfer time to/from the GPU." It was utterly trivial to get any paper into a conference by porting anything to the GPU and reporting a speedup. Most of the GPU related papers from this time were awful. I remember one in particular that claimed a 1000x speedup by timing just the amount of time it took for the kernel launch to the GPU instead of the actual kernel runtime, and somehow nobody (either the authors or the reviewers) realized that this was utterly impossible.

GPUs have more FLOPs and more memory bandwidth in exchange for requiring PCIe and lots of parallel work. if your algorithm needs those more than anything else (like cache), can minimize PCIe transfer time, and handles the whole massive parallelism thing well, then GPUs are a pretty good bet. If you can't, then they're not going to work particularly well.

(now, if you need to do 2D interpolation and can use the texture fetch hardware on the GPU to do it instead of a bunch of arbitrary math... yeah, that's a _huge_ performance increase because you get that interpolation for free from special-purpose hardware. but that's incredibly rare in practice)

I spent a lot of the past month improving the RenderScript (Android data-parallel compute, using C99 plus vectors) codegen to better work with the LLVM vectorizers, so I have a fair amount of experience with this exact question.

The vector types help in some ways--if you can use only vectors and do arithmetic on entire vectors only the SIMD codegen already works great--but they don't really help more than an intelligent vectorizer could. For example, the LLVM loop vectorizer can only handle loops where the induction variable changes by 1 or -1 each iteration. As a result, you couldn't set A[i], A[i+1], and A[i+2] in a for loop where i += 3 each iteration. If you could do that, you wouldn't really need vec3 in the first place. (also, the presence of any vector types whatsoever prevent any vectorization in LLVM right now, so...)

Another issue is that using vectors for storage and vectors for computation are very different things. I don't think anyone actually likes using vectors for computation, but vectors for storage make a lot of sense in some fields like image processing. However, as soon as you start operating on single channels, things get messy. Let's say you have a for loop where each iteration operates on a float4 as individual channels. Let's also say you want to turn each of those single channel operations into its own float4 operation, vectorizing across four iterations of the loop. Given most current SIMD ISAs, you're going to have to do four 32-bit loads of A[i].x, A[i+1].x, etc., then pack that into a vector, do your arithmetic ops, unpack the vector, and do four 32-bit writes to memory. Unsurprisingly, this is not particularly fast, and if you're doing one mul or FMA per channel, you shouldn't be vectorizing at all. This is why you see cost models in vectorizers (to prevent this sort of packing/unpacking from killing your performance when you enable your vectorizer) as well as why you see newer SIMD ISAs like AVX2 in Haswell including support for scatter/gather and permute.

The last issue is that it's trivial to break a vectorizer because of easy to overlook things like ailasing. Missing a single restrict will prevent vectorization if the compiler can't prove that pointers won't alias, for example (why do you think people still use fortran in HPC?). There's actually been a lot of great work here in LLVM over the past few months with new aliasing metadata for LLVM IR (http://llvm.org/docs/LangRef.html#noalias-and-alias-scope-me...), which is what I used to make the SLP vectorizer work with RenderScript in a way similar to ISPC (except in the compiler back end instead of the front end, because we don't even know the target ISA at the time the RS source is compiled to LLVM IR). I'll probably get the patch in AOSP in the next week or two if you want to keep an eye on that; it needs a newer LLVM version than what shipped in L and we're finishing up that rebase.

(honestly, I think that if you're trying to get good server CPU performance and you know exactly what CPU you're going to be using at compile time, you should be looking at ispc instead of doing SSE intrinsics yourself: https://ispc.github.io/ )

Desktop: high-end consumer GPUs have about 10-15x the single-precision FLOPs and 4-6x the bandwidth of a single Intel CPU socket. At this point, usually connected via PCIe Gen3. There are two real vendors (NVIDIA and AMD), and what comprises a system is generally the same (CPU + some number of GPUs).

Mobile: GPU has 3-5x the FLOPs of the CPU and no bandwidth advantage because of the shared memory pool between CPU and GPU. GPUs have very wide ranges of functionality. Even the CPUs behave very differently (Krait in Nexus 4 sometimes chews through code that the A15 in Nexus 10 chokes on and vice-versa). What comprises a system varies tremendously--CPU, CPU + GPU, CPU + GPU + other processors, etc.

A developer shouldn't be expected to have to tune for 20 different processors and system architectures in order to ship an app on the Android market. That's the problem we're trying to solve, not simply exposing access to GPU compute.

I worked on CUDA at NVIDIA for over four years and was the primary API designer for a large part of that time. I started on RS at Google in September.

Basically, he gives us too little credit for the execution model (it's young, it's improving very quickly and is not at all designed to emulate anything else that exists today) and assumes that GPU compute has the same tradeoffs on mobile as desktop (it doesn't at all). You'll see more from us soon.

I think it's a political move more than a technical one. WinRT lets MS say to Intel that Intel has to care about the tablet market and low-power processors or otherwise ARM will get a foothold in Windows (giving them easy access to the low-end of the laptop market in the next few years).

Of course, this would have worked a lot better if people cared about WinRT at all, but I'm sure that was the idea.

(full disclosure: used to work for NV on CUDA and did very extensive work on Titan, so I am probably biased)

If you think your existing MPI app is going to automatically scale to a heterogeneous architecture (high-power x86 on the main CPU, Xeon Phi cores on the accelerator) and get acceptable performance, sorry, it's not going to happen.

The fundamental constraints on 2012/2013 Xeon Phi performance that determine how apps should be written are exactly the same as current desktop GPUs (small, high-latency local memory that is not coherent with the rest of the system; relatively slow, high-latency link to CPU; ugly interactions with network cards in most environments; fundamental need to hide memory latency at all times). For any sort of performance beyond a standard Xeon, you're going to want to run a Xeon Phi as a targeted accelerator rather than offloading entire processes to it and using a standard MPI stack. This means you're going to be running in a hybrid host/device mode and using compiler directives or a specific parallel language and API to deal with on-chip execution and data transfer, which puts you in exactly the same solution space as with GPUs.

in other words: the Phi of today is not a panacea. you get better tools and more flexibility in terms of the programming model, but the fast path that any of its intended market would use in applications looks identical to GPUs.

I don't think that is true. If you're writing C, it's probably because you want to be close to the metal and want many of the guarantees that such proximity provides. If you're focused on that sort of thing, then it's definitely useful to understand what your compiler is actually outputting so you can react accordingly.

(I'm a C programmer, I don't look at assembly that often at all, but it's certainly helpful to be able to do so and my knowledge of the x86 ISA, calling conventions, etc has informed many decisions I've made in the past, especially re: performance)

The lack of any sort of physical connection to the NVIDIA GPU's display outputs is the fundamental feature of Optimus. Switchable graphics existed for years before Optimus introduced (and was usually usable under Linux without issue), but it was largely a niche feature because of the usability drawbacks.

You basically missed the entire point of it or why it's interesting.

Current Intel CPUs have a very small GPU built on to the die of the CPU. By buying the CPU, you're paying for an Intel GPU anyway.

At the same time, unlike CPU performance, GPU performance really does scale with die area; if you want more graphics performance, get a bigger chip with more ALUs/texture units/etc, and because graphics is so parallel everything will just go faster. However, larger chips mean larger amounts of leakage when the chip is powered but idle, which means that battery life can be significantly worse.

What Optimus does is allow the Intel GPU to be connected to the display hardware and be used most of the time (e.g., when you're looking at email or whatever) when high performance isn't called for. At that point, the NVIDIA GPU can be turned off completely, meaning no leakage and no battery life degradation. If you want high performance, the NVIDIA GPU is enabled on the fly, rendering is done on the NVIDIA GPU, and the final result is sent in some way to the Intel GPU, which can then use its actual display connections to put something on the LCD.

Prior to Optimus, there was generally a mux that would switch which GPU was outputting to the screen. This was messy because everything had to be done on one GPU or the other, it was noticeably heavyweight, occasionally required reboots, increased hardware complexity, etc.

The biggest issue with Optimus on Linux is that the infrastructure for the actual sharing of the rendered output didn't really exist until dmabuf appeared--you need two drivers to be able to safely share a piece of pinned system memory such that they can both DMA to/from that memory and be protected from any sort of bad behavior from each other. (I also think it's impossible to have two different drivers sharing the same X screen, which is why bumblebee works the way it does)

The hardest part about API design is picking the appropriate primitives in the first place. Use cases are relatively easy--somebody has a problem, come up with a solution--but any solution can be expressed in a myriad of different ways. The way that the API designer expresses that solution to the users of the API will impact the way code is written.

Users generally won't understand the implementation of the API, so instead they build a model of how they think the entire system operates. In the process, they make assumptions about performance, side effects, etc. that may be totally incorrect. Good APIs anticipate these assumptions and make them relatively easy to predict with some level of experience, either from elsewhere in the API or from similar APIs.

oh, I'm not claiming that x86 is going to win in mobile or anything like that. My only point is that based on devices shipping today, the choice of ISA does not cause huge power efficiency disparities and that there's no reason to think that will change going forward.