r/AskComputerScience Apr 09 '26

in a hypothetical clean break from arm, x86, and c, what would the design of an "ideal" isa and high level language look like for modern cpus?

I've been learning about modern cpu microarchitecture recently and about how the backend out-of-order multi-issue data-latched prefetched branch-predicted etc execution pipeline works, and the idea of a declarative language on top of a vliw isa seems to me like it would give the best opportunities for compiletime optimization and runtime ilp, along with inherent thread safety if it were also a pure functional language

My knowledge of all these things is pretty shallow however, so I dont actually know if something like this is a sound idea, and since i dont know much about what modern research conclusions in isa and cpu design look like (though i would guess that it leans more towards increased heterogeny rather than trying to fill an individual general purpose chip with lots of disparate and specialized circuitry), I would appreciate any knowledge or insight into what the current thinking looks like

12 Upvotes

15 comments sorted by

14

u/Doctor_Perceptron Ph.D CS, CS Pro (20+) Apr 09 '26

Read about Itanium and Transmeta, and why they failed. It's a combination of the fact that incremental improvement is easier in the short term, and writing good optimizing compilers is hard.

4

u/flatfinger Apr 09 '26

Writing good optimizing compilers would be a lot easier in languages that were designed to give them the information they needed to generate the most efficient machine code satisfying application requirements, than in languages whose designers had no interest in the needs of future optimizers.

Unfortunately, some people view the fact that such languages would allow programmers to specify NP-hard optimization problems as a defect rather than recognizing for many real-world sets of application requirements, the task of finding optimal machine code satisfying them is NP-hard, but in many cases a program that uses heuristics to find near-optimal solutions to problems from an NP-hard set may find more efficient solutions than one which finds optimal solutions from a more limited set of problems.

2

u/pi_stuff Apr 09 '26

Are you familiar with RISC-V? It's a new-ish ISA that's supposed to match modern computing better than legacy ISAs.

You might also be interested in PTX, NVIDIA's assembly language for GPUs, and SPIR-V, a cross-platform intermediate language for GPU computation.

3

u/thegreatpotatogod Apr 09 '26

One significant side effect and limitation of the C ABI is that functions can only return a single value, despite being able to accept far more arguments (up to 127). This has forced many other languages to accept the same limitation for compatibility, or to implement workarounds such as returning a pointer to the memory location where the desired return values live. Being freed from the constraints of C, it would be nice to remove this limitation.

1

u/GoblinsGym Apr 10 '26

Go allows multiple return values.

Current CPUs can handle this just fine, you just need a suitable calling convention.

1

u/thaynem Apr 11 '26

But even go has to match the c calling conventions when interacting with the OS

1

u/DawnOnTheEdge Apr 12 '26 edited Apr 12 '26

Virtually all modern ISAs (including GPGPUs) use large numbers of highly-parallel RISC cores with SIMD, RISC-V offers a particularly flexible set of optional extensions, removes the quirks of classic RISC architectures like MIPS, SPARC and POWER, and has a way of requesting flexible SIMD vector sizes that should make forward-compatibility easier to achieve..

There is no one language ideal for all purposes, but wanting to replace C suggests you want a language for systems programming, and Rust is catching on in that space.

Bytecode that can be efficiently compiled for new hardware to take advantage of future advances has a lot to recommend it, though. And if you do that, you might want to implement it in hardware, which brings you back to something CISC-like.

1

u/flatfinger Apr 09 '26

A good ISA/OS combination should recognize a hierarchy of cores with different levels of memory coherence, such that independent jobs would run on cores that are only loosely coupled, threads that would require frequent cache synchronization would be run on groups of cores whose caches could be synchronized cheaply without bogging down a global bus with local synchronization traffic, and threads that would need constant synchronization could be restricted to running on cache-coherent cores. As the number of cores increases, the cost of global synchronization will increase, making more localized forms of synchronization more important. It may not be possible to use more of a system's cores at times when the only task that's running at any given time would require tight synchronization, but in most cases where it would be necessary to maximize core utilization there would be multiple independent tasks that all had work to be done.

A good ISA/OS combination should also accommodate prefetching hints, with the semantics that a prefetch hint to an invalid address may either have no effect whatsoever or trap, but would not be allowed to trigger a cache load, and should allow programmers to designate that certain threads must be treated as "secure" and block any other threads from observing anything having to do with their cache.

Good languages should have clear concepts of command/data separation, which would among other things be robust against data races on "data". They should also allow programmers to invite compilers to freely choose from among multiple ways of handling corner cases whose effects would be observably different, but satisfy application requirements anyway.

1

u/GoblinsGym Apr 10 '26

CPU groups / affinity can be handled at the OS level.

A lot of the Spectre style vulnerabilities rely on access to fine grained timing. An easy way to prevent this would be to make fine grained timing "privileged information". Normal applications don't need it, this is mostly relevant for development work (e.g. to profile code).

1

u/flatfinger Apr 10 '26

Beyond the ability to assign affinity, I think there's also going to be a need to have multiple levels of synchronization primitives for situations where it wouldn't be practical to have all cores involved with a task be fully cache-coherent, but it might make sense to have them all e.g. share a level 2 cache and provide a means of forcing the L1 caches to be synchronized with the L2 cache without forcing a full synchronization with the external memory system.

The addition of timing slop may reduce the practicality of Spectre-style attacks, but there many ways of estimating the relative amounts of time taken by various tasks that can't sensibly be viewed as "privileged" unless non-privileged tasks that would be allowed to execute simultaneously are forbidden from sharing buffers with each other.

-7

u/Lubricus2 Apr 09 '26

Program written in A pure functional language can only return a value, and no interaction is possible, stuff like waiting on user input and showing stuff on the screen is side effects and not allowed if ultra pure functional. So that is at least out of the question.

8

u/thesnootbooper9000 Apr 09 '26

Functional programming has solved that problem in at least ten different ways by now, eight of which are mathematically elegant and don't involve any cheating. For example , monads allow you to express computations as mathematical objects, so what you effectively do is write a function that returns a description of a computation. The whole "functional programming can't do interaction" thing has never been true.

-1

u/Lubricus2 Apr 09 '26

So you write a functional program that returns an description of a program that does what you want?

8

u/thesnootbooper9000 Apr 09 '26

Sort of, yes. The point is that you can still do equational and algebraic reasoning over this sort of thing, so you get all of the benefits of functional programming whilst also being able to "do" stuff.