8 ms·
RAM-less Buffers
- kstenerud 9y agoSeriously, why all the sourpuss comments? The guy shows a fun little way to potentially use these registers in an innovative fashion and you jump all over him! You do understand that toys like this are meant to simulate the mind towards different ways of thinking, right? Great things are born from kennels of innovative thought. HN has really gone downhill...
- eecc 9y agoGuy is called Emily... my guess is it’s a gal
- Gatellicited 9y agoNo, she's a he. Emily is a curiously common name among autogynephiles. And to those who are about to scold me for having the bad taste to call someone by their biological sex, as you have been conditioned to do, let me say this: if you wish to indulge his paraphilia, that's your ill-advised prerogative, but don't demand the same foolishness from everyone else.
- vog 9y ago> Seriously, why all the sourpuss comments? ... a fun little way to potentially use these registers in an innovative fashion and you jump all over ... Not sure which "sourpuss comments" you mean. Perhaps a direct reply to one of those comments would be more helpful than this general one, which lumps together all fellow commenters. I only saw comments from people to appreciate the effort, have lots of experience in similar areas, and share their knowledge about the pitfalls they see. All very helpful and polite, as far as I can see.
- brownmenace 9y agobenchmarks plz
- jsjohnst 9y agoI think you’re missing the point of this post. This isn’t a general purpose technique they are advocating, but rather an interesting method that might prove useful to someone.
- kindfellow92 9y agoI think you’re missing the point. This is only useful if there is actually a measureable benefit.
- lgas 9y agoI'm not an assembly programmer, but is it possible there are benefits to treating SSE or AVX registers as a contiguous on-core buffer that are unrelated to performance?
- kindfellow92 9y agoIn the style of this article, Most probably not.
- pdkl95 9y agoI don't have enough experience with XMM registers (and SSE4 in general) to know if this is actually {useful,possible}, but a hypothetical use might be creating and using cryptographic keys such that the important numbers are never stored in main memory. If e.g. a decryption key is ever present in RAM, it's probably possible to steal it with a cold-boot attack that copies all of RAM. Once you have the RAM dump, the key can probably be found very quickly: for (secret_key_t *p = 0; p < RAM_SIZE; p++) { decode_with_key(p); } This does require significant physical access, but it works. I seem to remember reading ~1.5 years ago about a turnkey forensics kit (bottle of refrigerant included) for doing cold boot attacks? Regardless, more ways to protect keys is could be really useful. https://en.wikipedia.org/wiki/TRESOR https://en.wikipedia.org/wiki/TRESOR
- 9y ago
- gruez 9y agowhat's the point of using xmm registers when they'll get clobbered (or have to be moved back to memory) whenever you need to do a floating point operation? at least with ymm/zmm you can hope that you're not using AVX. >The reason why we won't be considering other operating systems is because the System V ABI doesn't preserve any of the XMM registers between calls and puts the burden on the caller to save them on the stack. If you think about it, this sort of defeats the purpose of using a register buffer if we're always going to be pushing our bytes to memory in user space. as opposed to windows? regardless of whether it's the caller/callee's job to preserve registers, the result is the same.
- phire 9y ago> what's the point of using xmm registers when they'll get clobbered (or have to be moved back to memory) whenever you need to do a floating point operation? at least with ymm/zmm you can hope that you're not using AVX. Nope, because SSE operations are explictly defined as setting the upper bits of the ymm/zmm registers to zero. > as opposed to windows? regardless of whether it's the caller/callee's job to preserve registers, the result is the same. There is a huge difference, with caller saved registers, the caller must compulsively save all registers it's using to the stack before it calls a function. With callee saved registers, if the callee doesn't use the registers, then it doesn't need to save them and a bunch of extra push/pops are saved. It is optimal to have a mixture of caller and callee saved registers, so the compiler pick what type it uses for each function/variable.
- Karliss 9y agoSplitting inline asm in to multiple blocks like shown in the article isn't a reliable way of using inline asm. Unless registers are specified in clobber list compiler isn't aware which registers are used by inline asm and may use them for other purpose. That can easily break by compiler overwriting them between inline asm blocks or other way around - inline asm overwriting values that compiler stored there.
- emily-c 9y agoThis is true and is precisely why it doesn't work without modification on higher optimization levels. I was originally going to write this article entirely in assembly but it seems like nobody wants to read an assembly dump! Instead even though it is malpractice to do so, the way the code is written in the article is still very clear even to people who don't really know assembly that well (I hope) and the concept is more clear. I will make that more clear in the article.
- lukego 9y agoThanks for writing this. My mind is buzzing now with ideas for how I could reserve and misuse a vector register :).
- emerged 9y agoAs an engineer who has spent thousands of hours programming SIMD assembly -- using them as buffers which can then be operated upon in batch is literally the entire reason they exist. So this reads to me as a programmer who isn't familiar with SIMD discovering one small part of why it exists and then writing an article about that as if it was a new idea outside the scope of normal SIMD usage. It's nice that this may give exposure into some low level details to those unfamiliar, but it isn't an innovation.
- emily-c 9y agoInnovation? That's quite a stretch. Using them together as a contiguous buffer is the not the reason they exist. Not quite sure how you took the article like you did but I have added some extra clarification that this is /not/ how they were designed to be used as well as another example.
- emerged 9y agoOf course they are. You load the registers with data from RAM. You permute the entire array and/or insert/extract individual elements. They are in fundamental nature a contiguous array. Most often you are literally loading them with a contiguous array from memory so you can work with it more efficiently before writing it back to memory. Downvote me as much as you want for saying so but it is the literal reason why the registers and instructions exist.
- joshAg 9y agoAren't they designed specifically for SIMD instructions though? This seems to be more just using them as another cache layer and not using them for their intended-SIMD use.
- emerged 9y agoI'm baffled by the downvotes that I'm receiving / why this is a controversial opinion. When you program SIMD, the registers are literally a temporary cache so that you can work with the data without touching RAM. The instructions are designed to load/store/manipulate these cached buffers. I didn't mean any offense to OP, if that's the cause for bad response. I've been using these instructions for well over a decade and the description given is without exaggeration the precise reason they exist and is what I've always used them for.
- cjbprime 9y agoThanks, interesting!
- DiabloD3 9y agoThis is really neat, but when a thread/process state enables MMX/SSE/AVX registers, it increases the cost of context switching (on Linux and other OSes) because they only restore registers they know could have been use (ie, if it has not called MMX/SSE/AVX ops yet, it does not save/restore XMM/YMM/ZMM registers). There have been cases where autovectorization in compilers have produced good SIMD versions of code (which is still considered a hard thing to do in some cases), but was still slower during certain benchmarks that did high thread counts (ergo, absurd amounts of CPU time wasted on context switching), but beat non-vectorized in less loaded situations.
- cybergoat 9y agoThis is rather clever! What immediately came to mind was perhaps you want to hide a secret key from entering memory. If this was done in kernel mode, you would be able to disable interrupts/task switching execute the "secret" stuff, and continue on your merry way...