HNHacker News
TopNewBestAskShowJobs

obl

1,695 karma · joined August 9, 2015

submissionscomments
obl··on One year of C
very good point on the "addresses compare == iff same object" rule.

In that case though, I think clang is right to optimize the callee (but it does introduce a problem in the caller) :

the only place you could do the equality check and observe the rule being broken is before the callee returns since the lifetime of its variable is bound to the call.

It seems that clang will not let the return pointer alias a local in the caller except when the call is the initialization of said local.

So if the caller goes :

foo x; leak(&x); x = returns_foo();

the memory will be temporary stack (and then memcpy), thus upholding the rule. (and it seems to me that this inefficiency is really required to respect the standard if we actually leak the pointer)

in the case :

foo x = returns_foo();

clang will pass the actual address of x down but that's before the object exists (and its address cannot be known yet) so the rule is still fine.

I stand corrected though, this does mean that RVO would be useful for C as well, as a way to relax the aliasing rule.

edit: nevermind that, in the first case it's perfectly legal to read/write foo through the pointer downstream so you cannot make the optimization anyway.

obl··on One year of C
Thanks. Unless something is escaping me, that's an optimizer bug. I'm pretty sure the ABI allows you to do whatever you want with the sret pointer, including passing it to another function to chain return for free.

I guess you could say that RVO is more robust since it's implemented in the frontend and does not rely on finding the optimization after a fair amount of lowering.

Edit: I don't have time to debug this but at least for llvm, I think this optimization should trigger in the optimizer's memcpy elimination pass ( https://github.com/llvm-mirror/llvm/blob/0818e789cb58fbf6b5e... ).

However I don't see why clang could not simply apply the RVO logic to C code as well.

obl··on One year of C
> Note also that C doesn't have return-value-optimization, hence all your struct-returning functions will cause a call to memcpy (won't happen when compiled in C++ mode of course).

What ?

RVO is precisely needed because a copy in C++ can run arbitrary code and so is not as easy to ellide as a memcpy. RVO is basically a promess you make to have your copy constructor & destructor be semantically harmless compared to a memcpy.

There is no need for RVO in C.

obl··on Show HN: Slack Lunch Club
when the actual problem you are solving is uninteresting, you can at least come up with complex configuration puzzles and bugs to entertain yourself
obl··on Intel Shows Xeon Scalable Gold 6138P with Integrated FPGA, Shipping to Vendors
HDLs are fine. I've found the tooling around them to be quite atrocious (slow, buggy, opaque, gui-based) though. Be it for synthesis, simulation, or even just compiler errors it's pretty bad compared to software.
obl··on Is Prefix of String in Table? a Journey into SIMD String Processing
in itself pointer chasing does not mean misusing CPU caches (your dataset could fit in cache and you could be pointer chasing inside it).

the main issue that is strictly due to pointer chasing is that you risk having long dependency chains in your instruction stream (address of the load depends on the result of the previous load, the address of which depends on the result of ...).

This is pretty bad for a modern CPU since a lot of the speed comes from overlapping independent computations.

obl··on Self-Awareness for Introverts [pdf]
right. his (1995) phd thesis is a classic for anyone interested in optimizing compilers http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17....
obl··on C Is Not a Low-Level Language
The point of dynamic optimizations (such as ooo) is not only to hide implementation details (such as register file size) but very much to take advantage of dynamic opportunities that simply cannot be known statically. The optimal schedule can be very different depending on whether some load hit L1 vs L2 or even was forwarded from the store buffer.

There are some classes of very regular algorithm where you could probably predict everything (and handle the memory hierarchy) statically, such as GEMM, but it's not very common.

obl··on The quadratic formula and low-precision arithmetic
inverse bilinear map is a good example where, even if there is an analytical solution, it's often more robust to just do a couple newton iterations until you get down to machine precision.

added benefit is that it carries on in 3D (although with a larger jacobian of course).

obl··on Jim Keller Joins Intel to Lead Silicon Engineering
very curious if anyone has info on what he will be working on if it's any specific chip family. mainline x86 ? GEN gpus ? phis ? something else ?
obl··on What you get is what you C: Controlling side effects in mainstream C compilers [pdf]
That's fine if you're writing assembly.

Compilers are free to use UB from the standard to optimize and absolutely do not guarantee you to emit machine loads and store naively as specified in the C source.

At least for clang I'm pretty sure they decided _not_ to give knowledge of, e.g., the zero low bits of an int pointer to the optimizer since many people are relying on it. That might not be the case in the future or another compiler.

Here is a thread discussing that http://lists.llvm.org/pipermail/llvm-dev/2016-January/094012...

obl··on First LED cinema screen in the U.S.A. officially opened
running a smaller, continuous, current through them.

PWM is done because it's cheap to implement given a fixed power rail and a digital control : need a single/couple of power switches that can even be integrated on die for low-ish power targets. continuous things usually need some kind of discrete filters, that means more components etc

obl··on UAF vulnerability in the Menu Management Component of Window Manager
yes, this is a troubling statement.

I'd imagine there are some computerized systems between the manual counting and the actual result, but still.

obl··on Is sorted using SIMD instructions
you can saturate memory bandwidth without SIMD, since you can issue at least 2 8-byte scalar loads per cycle. it does not leave much room for actual processing though
obl··on WebAssembly architecture for Go
I'm assuming it's because they wanted existing js/asm.js JITs to easily accept wasm, and those only see structured control flow.
obl··on Hobbes – A language and an embedded JIT compiler
any plan to move beyond "allocate linearly and never free anything" memory management ?

semantics look nice and coherent but unfortunately without some kind (automatic or manual) of memory management it's not usable as a general purpose tool.

obl··on Ryzen Community Update #2
I don't think the article states that the improvement in performance isn't the same for intel CPUs.

maybe they just optimized the game.

obl··on Apple proposes new web 3D graphics API
xbox
obl··on 1.1B Taxi Rides on Kdb+/q and 4 Xeon Phi CPUs
is it ? those things are trivial enough to be entirely bandwidth limited. total_amount is 4 byte, passenger_count is 1 and those are tightly packed in a column layout. streaming through that in 150ms is almost within the reach of a single normal chip with dual channel DDR3 ram.

Of course, not quite, and that's discounting the (small) sync overhead but still, no need to shell out 4 big servers, overpriced phi chips and fancy wide bus memory.

obl··on Add a const here, delete a const there
Would appreciate a reference on that if you have it handy.

Is this more of a whole program measured X% regression on some perf benchs, or specific target cases where the codegen is notably worse ?

obl··on A Tourist’s Guide to the LLVM Source Code
Unfortunately that's only superficially true. You have to care about GC interop, unwind & debug dwarf data, implementing part of the ABI in the frontend, and of course the occasional bugs when you exercise code path that clang does not.

Because of this, enabling a new backend is a substantial amount of work even if the instruction selection/generation is indeed taken care of for you.

obl··on A new year resolution to have Crystal reach the 1.0 milestone in 2017
Text templating can't possibly be better than (quasi)quoting.

> you're essentially just writing crystal code

even more so in a quasiquote, since you don't have to worry about adding extraneous parenthesis "just in case" etc.

Having structured input is already way better than full token-level solutions like C, but why not go all the way ?

obl··on Linux: Controlling access to the memory cache
Unless you want programmers to explicitely manage this fast memory the hardware is a better place to do those optimizations than the software.

Compilers (even the high-end modern ones) are very quickly clueless about both memory and execution profiles. Those problems are hard to reason about statically. Is this pointer the same as this other one ? Will this loop be executed 10 times or 10^6 times ? The hardware being a dynamic optimizer has a lot of runtime information (pointer values, cache entry usage, ...) to take advantage of.

Sure, one can argue that we just need better JITs, PGO, and programming languages that are easier to analyze statically. In the current state of affair we are way better off leaving this to the hardware.

By the way you do have "some" control over it using NT moves on x86. Turns out almost nobody uses them except by hand in very specific peak-bandwidth code. Compilers don't dare emitting those since the penalty of getting it wrong outweights the benefits of getting it right.

obl··on Hotpatching a C Function on x86
as for the synchronization use case, even though it's probably way more expensive to invalidate another thread's instruction cache than any other usual sync. method, it can be useful if there is a huge number of synchronization point but it happens very rarely and you don't want to bloat the code with explicit checks everywhere.

An example of that is garbage collection safepoints, although in that case you also need to be able to patch a function in the middle (any potentially unbounded control flow loop)

obl··on DeepMind Challenges for StarCraft
I think the point was mostly to only let the bot have as much information as a player would get on the screen : no omniscient knowledge about the state of every visible unit on the map. You'd probably also want to rate limit the inputs, including changing the viewport position, to something reasonable.
obl··on A toy generational garbage collector
at first glance it seems to be missing a write barrier to catch new references from old gen to new gen, which is a very important part of any generational collector
obl··on Off-heap Memory in Apache Flink and the curious JIT compiler
The advantage of any checked memory management scheme, be it a runtime thing like a tracing gc or a fancy type system, is not to give a tighter over-approximation of liveness but to guarantee that you never under-approximate it.

In other words, preventing memory leaks is undecidable, but you can at least be sure you're not freeing useful memory.

obl··on Tracing JITs and modern CPUs part 3: A bad case
This is wrong. The notion of predictability in modern branch predictors is much more sophisticated than simply "strongly taken"/"strongly not taken". i%2==0 is periodic of period 2. If I am to believe Agner, we've been successful in perfectly predicting repetitive patterns of period up to 5 since the Pentium II. A recent chip is considerably smarter than that.
obl··on Tracing JITs and modern CPUs part 3: A bad case
The big advantage in optimizing a trace at a time is that you don't have inbound control flow. In fact, the first transform that a tracing JIT does to the code (trace extraction) can be seen as removing every inbound CF edge except the loop head (leaving them in the deoptimized version of the trace).

One reason for that is that it makes optimization of the trace a lot easier since every forward dataflow problem (e.g. constant propagation or type inference) becomes more precise :

  if a is a string && b is a string
     x = concat(a,b)
  else if a is a int && b is a int
     x = add_int(a,b)
  else ...
if you have knowledge (thanks to runtime instrumentation) that most of the time the second branch is taken, you can transform it to :

  bail if a is a string && b is a string
  bail if !(a is a int && b is a int)
  x = add_int(a,b)
  ...
(where bail goes to the full code at the right place)

This version is a lot easier to analyze because you don't have to worry about what might be true in alternate branches : for example, since we can assume we didn't bail out, at the end of this snippet x is always an integer.

There is no reason to my knowledge why they couldn't support unbiased branches by including them in a trace, but it would complicate the implementation of various (forward) optimizing passes which don't have to worry about control flow in a single-trace model.

← PreviousPage 3 of 3