7 ms·
Cost of a Integer Cast in Go
- anonymoushn 4y agoIt may be useful to have a look at the assembly. There's probably no instruction corresponding to the cast, you just get a different arithmetic instruction that uses the bottom X bits. For a comparison between code with and without a cast between signed and unsigned ints of the same width, I would expect exactly the same instructions to be used.
- gbin 4y agoI agree... The compiler can make a lot of assumptions on such a simple operation, you have to look at the assembly. In other more complex cast cases it might be slower so I would not assume anything.
- tankenmate 4y agoThis may also depend on the architecture, what may be free or close to free on AArch64 may not be the case on x86_64 for example. Also of course, the the relative costs (e.g. 3x for float cast) may be different as well.
- PaulKeeble 4y agoThe line x += int32(i) Produces the assembler line 0x001e 00030 (.\cast_test.go:10) ADDL CX, DX In comparison the code x += i is using 0x001e 00030 (.\cast_test.go:19) ADDQ CX, DX The results are definitely different since the ADDL is for 32 bits and ADDQ is 64 bits and that is how its achieving the cast. Not sure the intent of the benchmark (the cost of a cast) is being captured directly since we have a specialist instruction for add to do the casting. But when you think about it ADDL 0, $Val achieves a cast and its 1 instruction so its not expensive at all and there may be something better than that for explicit casts, I doubt there is worse. Its basically free, I see no performance difference between them and that fits with expectations since casting is just throwing away all the top bits.
- anonymoushn 4y agoThanks. This is what I said I expected, given that int32 and int are different widths.
- Someone 4y agoNot only useful, but required. They have to check that the code is performing the intended operation and, even, that the loop still is there (https://kristerw.blogspot.com/2019/04/how-llvm-optimizes-geometric-sums.html https://kristerw.blogspot.com/2019/04/how-llvm-optimizes-geo... shows how gcc and clang remove some loops. The loops used here have simple forms, too, and could fall to the same type of optimization)
- tehmillhouse 4y agoAs a compiler guy, I'd appreciate some look at the layers of abstraction in-between (so, ASM). Microbenchmarks are famously jittery on modern CPUs due to cache effects, branch prediction, process eviction, data dependencies, pipeline stalls, OoO execution, instruction level parallelism, etc. You have to be really careful to ensure the numbers you're getting are really coming from the thing you're trying to benchmark, and aren't corrupted beyond recognition by your benchmarking harness. Some of these questions would surely be trivial if I actually knew any Go, but I'm left wondering: * What does the machine code / assembly look like for this? What does the cast compile down to? * What's `int` an alias for? I assume 64-bit-signed-integer? * Are integer casts checked in go? Would an overflowing cast fault?
- anonymoushn 4y agoint is defined to be the pointer width (or something like this), so probably int64 where the OP is running their code. integer casts are unchecked.
- fredrikholm 4y ago* https://godbolt.org/z/3dEdha44W https://godbolt.org/z/3dEdha44W * Architecture based, so 32 or 64 bit signed integer. * No faults. Signed become -1 and unsigned become MAX.
- Thaxll 4y agoThis is using GCC Go which no-one actually uses. Edit: why I'm being downvoted: https://go.godbolt.org/z/699d7KjWr https://go.godbolt.org/z/699d7KjWr
- kubb 4y agoChecking how many language subtleties you can point out is no doubt a good interview if you're looking for people experienced in a specific language. It strikes me as so different from what the FAANGs are doing: they ask you to write trivial algorithms on the whiteboard, which apparently filters 99% of engineers. Theoretically you can have a good candidate that doesn't know e.g. that appending to a slice passed in a function argument is a recipe for disaster. You'd show them the door over something that they could learn in a day.
- Barrin92 4y agotheoretically sure but chances are any good engineer knows that stuff and doesn't need to learn it, and FAANG can filter heavily because they get a lot of applicants. Basically if you don't know something you could have learned in a day in preparation for an interview at a top paying company that in itself is a sufficient signal.
- kergonath 4y agoThere are many more “things you can learn in a day” than there are available days to do it, though. Nobody will ever know all the possible tiny simple things. I would think in general that it’s better to select people who adapt and learn quickly rather than people who seem to know everything but you’re right: we are not fishing in the same pond as the FAANGs.
- kevincox 4y agoYou are making a lot of assumptions about the interview. Code review is an important part of the development process and seeing candidates who can suggest improvements to code is valuable. You seem to be assuming that the intended answers are language subtitles but I don't see evidence of that in the post.
- nemo1618 4y ago> Theoretically you can have a good candidate that doesn't know e.g. that appending to a slice passed in a function argument is a recipe for disaster. Huh? This is a common pattern. (hash.Hash).Sum, strconv.AppendInt, etc. I think you're referring to the fact that append can mutate existing memory (that is, it doesn't always allocate new memory), but in practice, this is rarely an issue, because, by convention, functions that append to a slice always return that slice.
- foota 4y agoIt's weird to see this analysis without any look at the generated assembly. They've also added a data dependency between benchmark loops, which is going to matter. Depending on the size they're testing with they're also just going to be benchmarking memory bandwidth.
- anonymoushn 4y agoThe code does not seem to perform any reads or writes other than to registers, so I would be surprised if memory bandwidth mattered.
- foota 4y agoIiuc it's iterating over a list of integers? Reading those from memory requires bandwidth. Edit: nevermind, I thought i was from an array, not just incremented.
- wruza 4y agoThis kind of benchmark makes zero sense. Sorry for being straightforward, it would be okay for someone who only starts programming, but this "have been doing interviews" part leaves an aftertaste. One must know their shit before "present a small chunk of code and ask them to review it over 15 minutes pointing out any issues they see".
- beanjuiceII 4y agoHonestly I can't even understand how this is real...this seems like exactly the wrong person I want doing interviews and even as a developer at my company
- traceroute66 4y agoI have to say I don't understand the point of debates like this when it comes to Go (its like the age-old "+" vs "strings.Builder" debate for concatenation). The point of Go is that its quick to learn, quick to get stuff done, and its got a fantastic stdlib that enables you to get most modern things out-of-the box. If someone is worrying about the cost of an integer cast in Go, then either: (a) They are using the wrong language and should be using something more low-level (e.g. Rust, C etc.) instead. (b) Like many who went before them, they are engaging in premature optimisation I'd put money on most people falling head-first into (b).
- anonymoushn 4y agoIt seems like there are a lot of posts online about how any effort at all to understand how code is executed and what tradeoffs are being made is a case of premature optimization.
- Retric 4y agoI don’t think that’s what people are complaining about. Doing a poor job is. For example += on floats is slower than += on integers. So does casting actually take 3x as long or is that an artifact of poor test design?
- dvfjsdhgfv 4y agoBy your logic, any attempt to optimize code written in Go makes no sense. But there are many of us who use go for the reasons you described and still care about efficiency, and especially about cases where trivial changes have significant consequences (one can argue if this particular article qualifies or not).
- avgcorrection 4y agoNo, not by their logic. The question is presented as a filter. A filter needs to be (1) so obvious that it is learned by osmosis for a good practitioner, or (2) so useful that they are going to need it in their daily work. Why would any of these two hold for a Go dev job?
- deleted 4y ago[deleted]
- Const-me 4y ago> about 3x the overhead to convert from int to float. That 3x overhead has nothing to do with converting types. A CPU can't compute x += y before it has the old value of the x. This is called "data dependency chain". Modern AMD64 CPUs have 1 cycle of latency to add integers, 3 cycles of latency to add FP32 or FP64 numbers. This means no matter what else is in the loop, a loop which increments a single float or double variable can't possibly be faster than 3 cycles / iteration. As demonstrated by the OP, Apple M1 is very similar in that regard.
- vikingerik 4y agoParallelism can break that speed limit, at least in theory. You could use four different registers to hold x+y, x+2y, x+3y, x+4y and run four instances of the loop in parallel, if there are no other data dependencies. I'm not sure if hardware microcode can be smart enough to detect that and do it with register renaming and such, but a sufficiently smart compiler could. (Or realistically it would be optimized into SIMD instructions; what I said in the first paragraph is really an ad-hoc implementation of SIMD.)
- Const-me 4y ago> run four instances of the loop in parallel Indeed, here’s an example which uses even higher latency FMA instructions to accumulate: https://stackoverflow.com/a/59495197/126995 https://stackoverflow.com/a/59495197/126995 The example uses 4 independent accumulators to saturate the throughput, instead of stalling on the latency. BTW, on most modern CPUs that code doesn’t saturate the compute throughput, the bottleneck is loads. > a sufficiently smart compiler could They tend to avoid doing that for floats, for accuracy reasons: float addition ain’t associative.
- makapuf 4y ago> They tend to avoid doing that for floats, for accuracy reasons: float addition ain’t associative. Indeed, unless you use -ffast-math (also known as -fidontcareaboutthe results). See https://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do#22135559 https://stackoverflow.com/questions/7420665/what-does-gccs-f...
- trelane 4y agoThe benchmarks are interesting, but that's not what caught my attention. I'm not convinced finding increasingly esoteric bugs in an interviewer-selected language is an effective gauge of coding ability. I expect this is actually worse than whiteboard coding.
- robertlagrant 4y agoWhy is that?
- nicce 4y agoWhile the programmer should produce clean, good and optimised code, finding bugs and errors is more job for a pentester. Experienced programmers can easily detect these, but that is not their main job. Programmer should be able to solve problems and apply the selected language for solving these problems as efficiently as possible.
- robertlagrant 4y agoYou think a penetration tester should find bugs in code? They're looking for security weaknesses only, and almost never by looking at the code. Your method may be the most expensive possible.
- nicce 4y agoEvery bug is a weakness at some level. The most efficient way in bug bounties currently to make money is by reviewing open-source code. Manually testing takes huge amount of time. You can also automate code review for low hanging fruits with tools like semgrep or GitHub's code scanning. Of course programmers should test their code themselves and minimise the bugs, but their work it not to look for them.
- eptcyka 4y ago>Of course programmers should test their code themselves and minimise the bugs, but their work it not to look for them. I have to respectfully WAT. Code review should be a part of everybody's workflow. And all programmers involved should be looking out for bugs. The best bugs are those which were never merged in the first place.
- thayne 4y agoSo all the tests were done on an m1 mac. Is there any difference on x86_64? I wouldn't expect there to be, but unless this program is only going to be running on new macs, this analysis isn't really complete.
- ThinkBeat 4y agoWould guessing how many instructions the code uses be better assessed looking at the assembler files (Might need to decompile to get it, not too familiar with the Go toolchain) Or a good debugger?