|
Dr. Stab posted:Knowing x86 assembly is probably a downside when it comes to application development.
|
# ? Apr 29, 2016 01:50 |
|
|
# ? Jun 7, 2024 22:52 |
|
Soricidus posted:I'm terribly sorry, but if it means you will be continuing to place a space character between arrays and their opening brackets, then I am not able to grant you permission to do that. The horror. The horror. JawnV6 posted:But that's true of MIPS and the MSP430 as well. Is there a single processor where comparison to zero isn't simpler than any other comparison?
|
# ? Apr 29, 2016 02:08 |
|
It's an optimization on x86 because both SUB and DEC set ZF as appropriate so you don't actually have to do a comparison.
|
# ? Apr 29, 2016 02:12 |
|
Ironically it's probably slower because iterating through the array backwards breaks prefetching so you hit a bunch more cache misses. Except the array is probably not large enough and whether it's a net optimization or inefficiency is completely irrelevant. Still, don't be too clever.
|
# ? Apr 29, 2016 02:34 |
|
C code:
Really more of a horror that the language/compiler doesn't help you out here at all, as the author's intention is pretty clear.
|
# ? Apr 29, 2016 02:50 |
|
ExcessBLarg! posted:Ironically it's probably slower because iterating through the array backwards breaks prefetching so you hit a bunch more cache misses. Yeah, so much optimization is done on the compiler and machine level that you should be focusing optimization on algorithms (usually you'll want to solve something in O(nlogn) rather than O(n2), if you know that you're going to be getting to high enough n!) and whatever comes up as a bottleneck in profiling.
|
# ? Apr 29, 2016 03:10 |
|
ExcessBLarg! posted:Ironically it's probably slower because iterating through the array backwards breaks prefetching so you hit a bunch more cache misses. Pretty sure modern CPUs prefetch for both directions of memory access.
|
# ? Apr 29, 2016 03:21 |
|
Subjunctive posted:Pretty sure modern CPUs prefetch for both directions of memory access.
|
# ? Apr 29, 2016 03:45 |
|
laugh all you want, but I used to be a Flash programmer, where these things were literally required since the compiler is poop. so this brought back memories for me. the compiler also used to emit three times as many labels for a for loop as a while loop. so you were told never to use for loops if you wanted a 60fps game. written by a super friendly and awesome guy, but still poop other Flash facts: shorter variable names are faster since it simply uses a hashmap for its scope, and locals are stored, name and all.
|
# ? Apr 29, 2016 04:30 |
|
Absurd Alhazred posted:Yeah, so much optimization is done on the compiler and machine level that you should be focusing optimization on algorithms (usually you'll want to solve something in O(nlogn) rather than O(n2), if you know that you're going to be getting to high enough n!) and whatever comes up as a bottleneck in profiling. It depends on the problem domain and input size, but you shouldn't expect the compiler to optimize everything except asymptotic complexity if you actually gotta go fast. Parallelization, memory layout and vectorization all matter, to a factor of 10x to 10000x or so depending on the problem and hardware, and compilers for typical mainstream languages will not touch any of them unless you tell them exactly what you want. So while you don't have to worry about making the compiler pick the "faster" comparison before a branch to go fast, you do still occasionally need a list of vector intrinsics and willingness to smash your head against all the obscure race conditions that you introduced last week. Fortunately for humanity, we have solved this problem by making CPUs fast well beyond the point where our inability to make very good use of them matters in almost all applications. The majority of programmers can cheerfully code for readability and alterability (or lazyness and expedience), rather than carefully encode their data in Morton order or whatever. There's no force like brute force, after all.
|
# ? Apr 29, 2016 05:31 |
|
john donne posted:
I'm the horror too, because when I can loop in either direction in Haskell, I typically write: code:
code:
99% of the time, I just fold over [0..(n - 1)], since list fusion gives me the same code.
|
# ? Apr 29, 2016 08:35 |
|
Zemyla posted:I'm the horror too, because when I can loop in either direction in Haskell, I typically write: That's typical with functional languages, though (or recursion in procedural languages, for that matter). We generally think of recursion as "shrinking to a base value" even when it could strictly be done the other direction. The problem with iterating backwards with an actual for loop is like 99% that it's weird, and the less weird it is, the easier it is to understand. You can sacrifice clarity or elegance for performance sometimes, but in this case the only reason it was done was a dubious, almost certainly nonexistant performance gain. Linear Zoetrope fucked around with this message at 08:45 on Apr 29, 2016 |
# ? Apr 29, 2016 08:38 |
|
In any case, the correct way to write the reverse loop iscode:
|
# ? Apr 29, 2016 09:34 |
|
Suspicious Dish posted:laugh all you want, but I used to be a Flash programmer, where these things were literally required since the compiler is poop. so this brought back memories for me. the compiler also used to emit three times as many labels for a for loop as a while loop. so you were told never to use for loops if you wanted a 60fps game. I hope you have also used that one xml reader that was written in actionscript instead of the built-in one, because the built-in one was slower.
|
# ? Apr 29, 2016 10:57 |
|
Soricidus posted:In any case, the correct way to write the reverse loop is This is as awesome as it is horrifying.
|
# ? Apr 29, 2016 11:15 |
|
Soricidus posted:In any case, the correct way to write the reverse loop is This is what I was thinking, decrementing has the benefit of not requiring the allocation of another register, if it can be overwritten. Another perk is that if you're fastcalling, it is already there! The end of 3.7.2 of the intel optimization manual has the answer to the prefetching question, but I'm on my phone so I can't quote it. Also you can use the prefetch instruction. dougdrums fucked around with this message at 14:25 on Apr 29, 2016 |
# ? Apr 29, 2016 14:10 |
|
ExcessBLarg! posted:Ironically it's probably slower because iterating through the array backwards breaks prefetching so you hit a bunch more cache misses. Backwards memcpy is actually (very slightly) faster than forwards on a bunch of Intel CPUs.
|
# ? Apr 29, 2016 15:17 |
|
Soricidus posted:In any case, the correct way to write the reverse loop is I'm going to use this in all of my refactor PRs from now on Also as you probably could have predicted, that collection was indeed like 8 items long, and that loop was found in one of the worst-architected applications I've ever seen.
|
# ? Apr 30, 2016 00:22 |
|
feedmegin posted:Qt is pretty good about binary compatibility within each major version, actually, though it does take some effort internally. Not too much effort, it's a well known pattern called pimpl. Qt has slight complications with pimpl related to some uses of its event dispatching system, but it's all mostly painless Cuntpunch posted:Excuse me you forgot to extend(or Implement) Vertebrate, so all your mammals are going to have broken movement methods. This is what the entity-component-system model was born for hackbunny fucked around with this message at 02:43 on Apr 30, 2016 |
# ? Apr 30, 2016 02:40 |
|
hackbunny posted:Not too much effort, it's a well known pattern called pimpl. I'm the indirect branch on every everything.
|
# ? Apr 30, 2016 02:43 |
|
isn't that what link-time optimization is for? can't most linkers inline simple functions like getters?
|
# ? Apr 30, 2016 04:14 |
|
Suspicious Dish posted:isn't that what link-time optimization is for? can't most linkers inline simple functions like getters? Pimpl means that you're using dynamic memory allocation everywhere and therefore you're less likely to have the object in your memory cache. Even if the linker inlines the getter it still has to get the info from memory. Linked-lists are slower than vectors (ArrayList) for the same reason that every new linked list item is at a new place in memory instead of right nearby.
|
# ? Apr 30, 2016 04:34 |
|
pimpl's memory impact isn't worse than just using a lot of reference types. it can obviously be taken to ridiculous extremes like separately allocating Point2Ds but if you just use it for large-ish types and/or at boundaries that are polymorphic anyway (i.e. already indirected and separately allocated) it's not a noticeable penalty and can actually improve locality vs. inlining the storage of everything i have no idea what subjunctive is saying, pimpl introduces an extra level of call but it's not indirect. lto will kill that neglible extra indirection when you're using the pimpl interface internally, but a lot of times you're using pimpl at library boundaries where lto won't help / isn't a performance bottleneck anyway. like i just wrote a pimpl library (for lldb's use) for looking up swift ast types from remote type metadata, there is really no plausible use of this library where a tiny issue delay in the pimpl thunk is going to show up vs. all the time it spends processing memory and performing i/o with the inferior process. that is how you are supposed to use pimpl
|
# ? Apr 30, 2016 06:02 |
|
Captain Cappy posted:Pimpl means that you're using dynamic memory allocation everywhere as opposed to using stack allocation for long-lived objects? what?
|
# ? Apr 30, 2016 07:28 |
|
rjmccall posted:i have no idea what subjunctive is saying, pimpl introduces an extra level of call but it's not indirect. lto will kill that neglible extra indirection when you're using the pimpl interface internally, but a lot of times you're using pimpl at library boundaries where lto won't help / isn't a performance bottleneck anyway. Sorry, yes, I'm referring to the extra indirection and the hand-wringing that I have seen accompany it. I am not seriously advocating against pimpl on the basic of that cost.
|
# ? Apr 30, 2016 14:42 |
|
Suspicious Dish posted:as opposed to using stack allocation for long-lived objects? what? Not necessarily stack allocation I guess, but the issue is that in the following example, your class's two objects are nowhere near eachother in memory. And yeah, this isn't a big deal for stuff like GUI components or other classes that there aren't a lot of, but it will ruin your cache hits if you put them in an array or vector. code:
|
# ? Apr 30, 2016 16:23 |
|
e: misread you
Soricidus fucked around with this message at 16:33 on Apr 30, 2016 |
# ? Apr 30, 2016 16:31 |
|
Out of nowhere in the past week, our lackluster contractor has started commenting like this *everywhere*code:
|
# ? May 5, 2016 16:55 |
|
That's actually a trademark of decompilers and other tools like that. Are you sure he's not stealing code?
|
# ? May 5, 2016 17:04 |
|
I've done that sometimes manually when I'm trying to cope with some ungodly huge function and it really is that hard to figure out what the close-curly corresponds to. Doing it everywhere? Nnnnnot so much.
|
# ? May 5, 2016 17:12 |
|
use code folding in those situations.
|
# ? May 5, 2016 18:10 |
|
Yeah, I probably should do that, but the added annoyance helps encourage me to refactor the code in question, so it balances out.
|
# ? May 5, 2016 18:25 |
|
Suspicious Dish posted:That's actually a trademark of decompilers and other tools like that. Are you sure he's not stealing code? I have met multiple human beings who habitually comment the ends of blocks (and in languages where the equivalent of "decompilation" would be obvious for reasons other than weirdo commenting, so I'm confident that isn't it).
|
# ? May 5, 2016 18:46 |
|
BobHoward posted:I have met multiple human beings who habitually comment the ends of blocks (and in languages where the equivalent of "decompilation" would be obvious for reasons other than weirdo commenting, so I'm confident that isn't it). Cuntpunch said he started out of nowhere, which points to it not being that insipid habit.
|
# ? May 5, 2016 19:04 |
|
BobHoward posted:I have met multiple human beings who habitually comment the ends of blocks (and in languages where the equivalent of "decompilation" would be obvious for reasons other than weirdo commenting, so I'm confident that isn't it). Yeah, that's all over the place in HDL's. I'm not sure if that was a stylistic choice or just necessary because of bad tools and giant code blocks.
|
# ? May 5, 2016 19:56 |
|
Suspicious Dish posted:That's actually a trademark of decompilers and other tools like that. Are you sure he's not stealing code? Yes, because I didn't include the gross tendency towards typos that, kindly, would be called the obliteration of the english language in my example comment
|
# ? May 5, 2016 20:44 |
|
BobHoward posted:I have met multiple human beings who habitually comment the ends of blocks (and in languages where the equivalent of "decompilation" would be obvious for reasons other than weirdo commenting, so I'm confident that isn't it). If I have to have deeply-nested things, like 3-d for loops, I will absolutely write comments like "// end for(i)".
|
# ? May 5, 2016 21:30 |
|
I was having a weird issue with matplotlib graphing the same graph twice, eventually I found the problem:code:
[1] [] I had refactored the plotting code into a function because I added the second graph, but I forgot to change the name of the variable to the argument. Mumblegrumble Python scoping idiosyncracies, I would've expected an error.
|
# ? May 6, 2016 00:42 |
|
The lack of block scoping and the lack of true multithreading are my biggest peeves with Python, and I'm honestly not certain which of the two is worse.
|
# ? May 6, 2016 00:58 |
|
|
# ? Jun 7, 2024 22:52 |
|
Threads are terrible, if that helps.
|
# ? May 6, 2016 00:59 |