HackerTrans
TopNewTrendsCommentsPastAskShowJobs

KMag

no profile record

comments

KMag
·3 года назад·discuss
But, going the other way, I worked for over a decade on Goldman Sach's SecDB system. It's a quirky steampunk alternative future that branched from our light cone around 1995. There's a globally distributed eventually consistent NoSQL database tightly integrated with a data-flow gradually-typed scripting language (and a very 1990s feel 16 color IDE). I'm sure in the late 1990s/early 2000s (before globally distributed NoSQL was popular and before gradual/dynamic typing had a resurgence) it was more like discovered alien technology than steampunk alternative future. (Also, with source code being executed from globally distributed immutable database snapshots, deployment is much nicer than anything else I've used to date. After release testing, set a database key to point to the latest snapshot, and you're deployed.)

There's a service that watches the transaction log of your regional replica so that you can make long-poll HTTP requests that return when any change matching your filter is committed. (Edit: usually the HTTP result handler is used to invalidate specific memoized results in the data flow graph, letting lazy re-evaluation re-fetch the database records as needed.)

It makes a lot of sense for a financial risk system, where you end up calculating millions of slight variations on a scenario. The data flow model with aggressive memoization makes this sort of thing much cheaper.

However, I saw plenty of systems written where you'd attempt to write your request to the next key matching some regex (and retry with the next key if it already existed), where your request would contain some parameters and the database key and/or filesystem path where results should be written.

Under-experience with databases easily results in rewriting a database using message queue/bus. Under-experience with message queues/busses easily results in rewriting a message queue/bus using a database.
KMag
·3 года назад·discuss
Right, but it's cleaner and better performant to use higher-level upcalls to the hypervisor rather than trapping and emulating every privileged instruction.

As it stands, the hypervisor needs to implement both trap-and-emulate and upcall handlers, and OSes need to implement both running on bare metal and (if they want to perform well on hypervisors) hypervisor upcalls.

If you want your hypervisor to support nested hypervisors, then I guess you'd still need to implement trap-and-emulate in the hypervisor to allow running a hypervisor on top. However, you at least remove the dual paths in the OS kernel if you just disallow the bare-metal case. This also allows a bit more flexibility in hardware implementation as you can change the hardware implementation and the instruction sequence in the hypervisor without needing to modify any legacy OS kernels.
KMag
·3 года назад·discuss
A while back, I read a Sun patent on not implementing some instructions and emulating them in the kernel's illegal operation trap handler. The whole patent seemed obvious to me, but I'm glad that it was patented and now expired, providing obvious prior art in any attempts to patent it today.

For MIT's 6.004 "Beta" processor loosely based on the DEC Alpha AXP, our test cases ran with a minimal kernel that would trap and emulate multiply, divide, etc. instructions using shifts and adds/subtracts, so we could implement more simple ALUs and still test the full instruction set.

In any case, particularly in the world of hypervisors, it doesn't seem too hard to deprecate an instruction and stop implementing it in hardware, and push that complexity into firmware. As long as the CPU covers the Popek and Goldberg virtualization requirements, hypervisors could be nested, and the firmware could implement a lowest level hypervisor that handles unimplemented instructions.

More generally, I wish ARM64, RISC-V, and other modern ISAs had taken DEC Alpha AXP's idea of restricting all of the privileged instructions to the firmware (PALCode in the Alpha's case) and basically implementing a single-tenant hypervisor in the firmware. The OS kernel always used an upcall instruction to the hypervisor/firmware to perform privileged operations. In other words, the OS kernel for Alpha was always paravirtualized. (UNSW's L4/Alpha microkernel was actually implemented in PALCode, so in that case, the L4 microkernel was the firmware-implemented hypervisor and the L4 syscalls were upcalls to the firmware.) As it stands, hypervisors need to both implement upcalls for efficiency and also implement trap-and-emulate functionality for OS kernels that aren't hypervisor-aware. The trap-and-emulate portions of the code are both lower performance and more complicated than the upcall handlers. Both hypervisors and OS kernels would be simpler if the platform guaranteed a hypervisor is always present.

Always having a firmware hypervisor also allows pushing even more complexity out of hardware into the firmware. The Alpha had a single privilege bit indicating if it was currently running in firmware/hypervisor (PALCode) mode, and the firmware could emulate an arbitrary number of privilege levels/rings. The Ultrix/Tru64 Unix/Linux firmware just emulated kernel and user modes, but the OpenVMS firmware emulated more levels/rings. x86's 5 rings (including "ring -1/hypervisor) could be efficiently emulated by hardware that only implements ring -1 (hypervisor) and ring 3 (user mode).

Edit: Taken to an extreme, you get something like Transmeta's Crusoe that pushed instruction decoding and scheduling into a firmware hypervisor JIT that works on the processor's microcode level. In retrospect, it seems that Crusoe went too far, at least as far as early 2000's technology could go. However, there's still plenty of optimization space in between the latest Intel processors on the extreme hardware complexity side and Transmeta's Crusoe on the extreme firmware complexity side.

Edit 2: In-order processors like (at least early) Intel Atom, P.A. Semi's PWRficient, and Transmeta's Crusoe tend to be more power-efficient. If the architecture designed for it, I could see a case for limited out-of-order hardware capability with hardware tracing and performance counters/reservoir sampling of instructions that caused pipeline stalls. The firmware could then use run-time information to JIT re-order the instruction streams in hotspots that weren't well-served by the hardware's limited out-of-order execution capacity. This might be a viable alternative to ARM's big.LITTLE, where the firmware (or kernel) kicks in to provide a performance boost to hotspots when plugged in, and executes as a simple in-order processor when lower power consumption is desired, without the extra complexity of separate pairs of cores for performance and efficiency. Hardware sampling of which speculations work out and which are wasted would presumably guide the firmware's attempts to efficiently re-optimize the hot spots.
KMag
·4 года назад·discuss
Or sometimes the lower bits, as at least used to be the case for integers in v8. (Also OCaml, but that's not dynamically typed. It simplifies the garbage collector to at least some times not require a pointer map for each type, just a flag in the object header to indicate if it contains any pointers, and then everything that isn't ints or pointers needs to be boxed.)
KMag
·4 года назад·discuss
From my reading, it's checking the maximum index into the circular buffer. That is, when it hits the end of the circular buffer, there's an assertion to check that they're properly wrapping the index back to the start of the buffer, but the assertion has an off-by-one error.

I presume you find a lot of circular buffers in SSD firmware, for wear-leveling reasons. Samsung's NILFS and NILFS2 are structured as circular buffer append-only logs, at least partly to avoid trusting the firmware wear-leveling.
KMag
·5 лет назад·discuss
> google uses AI to design chips in 6 hours

No, Google's AI is floorplanning[0] (basically routing and layout) human-designed logic in 6 hours. That headline is misleading.

It's kind of like having a compiler will billions of optimization flags and using AI to select a pretty near-optimal set of flags for a particular human-generated source file. We wouldn't call the output an AI-designed program, even though such AI would be really helpful.

Google is using AI as a heuristic for decently fast approximate solutions to the floorplanning problem, where (IIRC) optimal solutions are NP-hard.

It's an important step forward, and presumably a big time saver, but they're nowhere near giving the AI an instruction set spec or examples of inputs and outputs ad having the AI generate the logic.

[0] https://en.wikipedia.org/wiki/Floorplan_(microelectronics)
KMag
·5 лет назад·discuss
Will the specifications for the software also be machine-generated?

If the specifications are human-generated, then they're just a form of high-level source code, and your prediction boils down to future programming languages simultaneously improving programmer productivity and reducing resource usage. That's not a controversial prediction.

If I understand you correctly, I think you're correct that over time, we'll see an increase at the abstraction level at which most programming is done. I think the effort put into making compilers better at optimizing will largely follow market demand, which is a bit harder to predict.

One interesting direction is the Halide[0] domain-specific language for image/matrix/tensor transformations. The programs have 2 parts: a high-level description, and a set of program transformations that don't affect results, but make performance tradeoffs to tune the generated code for particular devices. The Halide site has links to some papers on applying machine learning to the tuning and optimization side of things.

I can imagine a more general purpose language along these lines, maybe in the form of a bunch of declarative rules that are semantically (though perhaps not syntactically) Prolog-like, plus a bunch of transformations that are effectively very high-level optimization passes before the compiler ever starts looking at traditional inlining, code motion, etc. optimizations.

At some point, maybe most programmers will just be writing machine learning objective functions, but at present, we don't have good engineering practice for writing safe and reliable objective functions. Given some of the degenerate examples of machine learning generating out-of-the-box solutions with objective functions (throwing pancakes to maximize the time before they hit the ground, tall robots that fall over to get their center of mass moving quickly, etc.), we're a long way from just handing a machine broad objectives and giving it broad leeway to write whatever code it deems best.

I suspect in the medium-term, we'll see a 3-way divergence in programming: (1) safety/security-critical programs generated from proofs (see Curry-Howard correspondence, and how the seL4 microkernel was developed) (2) performance-critical programs that are very intensive in terms of human expert time and (3) lots of cookie-cutter apps and websites being generated via machine learning from vague human-provided (under-)specifications.

[0] https://halide-lang.org/
KMag
·6 лет назад·discuss
> If you believe this, you won't believe what's in this box[1].

There's a fundamental difference between GPU code and vector CPU instructions, though. GPU shader instructions aren't interwoven with the CPU instructions.

Yes, if you restrict yourself to not arbitrarily mixing the vector code with the non-vector code, you can put the vector code off in a dedicated processor (GPU in this case). The GP explicitly stated that a lack of this restriction prevents efficiently farming it off to a coprocessor.
KMag
·10 лет назад·discuss
Last I used Go (granted, 2010), it refused to use the platform ABI, and shipped with kenc so that you could compile your C code for its ABI. So, it had C interop, but not binary interop with C. For the kind of interoperability you're talking about here, if each language uses its own ABI, we get O(N*N) complexity. Have things changed with the Go ABI, or at least its FFI?

I'm sure the Plan9 ABI variant used by Go makes more sense than the platform ABI, but supporting the platform ABI for FFI doesn't add much complexity at all to the compiler.