Hacker News new | past | comments | ask | show | jobs | submit login
Rust-GPU: Making Rust a first-class language and ecosystem for GPU code (github.com/embarkstudios)
197 points by zdw on Oct 23, 2020 | hide | past | favorite | 70 comments



I don't think Rust is very suitable for GPU programming, "first–class" or whatever. And it has not much to do with Rust itself. We have seen time and time again people write deeply inefficient overkill kernels in C for some basic stuff really. I should expect this would happen to Rust, too. In order to tackle this right, it seems, we really should treat GPUs and similar coprocessors for what they are—deeply data–parallel computation accelerators. You must design your pipelines with that in mind; this stuff is also very sensitive to data locality, as you might expect. Now, take a look at this Haskell-inspired language [1], which I think is much more viable in the long–term as far as data parallelism and composition goes. Admittedly it's not in itself designed for graphics, but that's okay. From their website: "Futhark is a small programming language designed to be compiled to efficient parallel code. It is a statically typed, data-parallel, and purely functional array language in the ML family, and comes with a heavily optimising ahead-of-time compiler that presently generates either GPU code via CUDA and OpenCL, or multi-threaded CPU code."

I can see that very much unlike Futhark, Rust-GPU is deeply graphics focused, but I argue that a very similar language can be made to accomodate if not all then most shader-specific things. In which case, Futhark would be a very good place to start.

[1]: https://futhark-lang.org/


Having a macro to convert a Rust-like DSL (with a focus on iterators to replace Futhark's higher order functions) to GPU via a Futhark-like compiler is doable and something I would love to see done.

It could be the rayon of GPU computing on Rust.



Yeah, this should be marked as a dupe of that, given it was only two days ago and gained substantial traction.


Somebody please, please make an equivalent to Tullio.jl for Rust ... by far the easiest way to write custom kernels


Man Rust seems like it’s really on fire at the lower levels right now, like it’s gonna replace C.


It has 60 years to catch up with C and 40 years to catch up with C++.

Don't mistake winning a few battles with winning the war.

So far C++ hasn't had much foothold on kernels and embedded, despite several victories.

Also note that NVIDIA is on ISO C++ and they have changed CUDA architecture to fit C++11 memory model.


Rust has been going for 10 years (5 years since 1.0); everything needs time for sure, but Rust has been building up to this point.


True, and it has been a remarkable progress, but it is yet far from being a SDK language on game engines and consoles.


I don't see C going away. That said, there does seem to be a cultural change afoot.


First, I think you might be a decade off on both accounts.

Second, the connectivity was not the same at the time, ideas travel much faster now.


Easy to validate,

C was born in 1972, so 48 years.

C++ was born in 1985, so 35 years.

I stand corrected on the matter.

As for ideas, traveling is not enough when at the reception end there isn't any willingness to accept them.


Rust's range is very impressive. It's almost equally at home doing systems work, embedded and CLI utilities


It's not unreasonable to expect it to replace C, but as a major Rust fan myself, I don't see it specifically taking aim at C. C++ is the monster under the bed.


Can you please elaborate on that? Both why not C and why C++ sounds really interesting.


Hardly it will fully replace C++ due to the pervasiveness of the language on many domains and also due to the C++ ecosystem that encompasses system programming; embedded systems; games and so on. For instance, the C++ ecosystem still outmatches rust regarding high performance libraries for several scientific computing domains; GUI graphical user interface libraries, such as Qt, MFC, wxWidget; Game engines and so on. In addition, Rust lacks openMP feature which allows parallelizing for-loops, which are widespread on scientific computing, for taking advantage of multi-core CPUs and from SIMD.


An outsider's perspective is that c and c++ are pretty similar except c++ is a little more ... powerful? More something for being a bigger language.

Rust is a bigger language.

There are other languages aiming to be small and a better c. Zig comes to mind.


C++ has a ton of baggage and is a very difficult language to use. There are too many language features and they all have years of warts.

Imagine PHP, but not memory safe. Mistakes cause segfaults, memory leaks, and can enable attackers write memory they shouldn't be able to access. To top it off, a lot of libraries are still written in "PHP4 style" and you've got to make use of them. C++ is really hard.

Both C and C++ require consideration of memory semantics, and they are both "hard" in this sense. You have to allocate and free memory deliberately and be conscious about what memory you're passing around. C is much simpler in design than C++. It doesn't have as many features, so it's harder to trip over. It doesn't necessarily make it easier to program, though.

Rust targets the same domains that C and C++ do: systems programing (operating systems and drivers), real time programming (robotics and control software), graphics and games, etc. These are places where explicit memory management is important. Rust does so while being much easier to write. The language leverages new programming language theory and design to protect memory from being written incorrectly. The memory semantics are baked into the language design and checked at compile time. Bad code (in terms of memory and async) simply doesn't compile.

Rust does this while being just as fast as C and C++.

In addition, Rust has a ton of modern features that make it feel like Ruby. Functional idioms, zero-cost abstractions, a modern trait-based type system, generics, macros, and a beautiful package manager and package ecosystem that is better than Ruby and npm.

Rust is going to beat both of these languages.


IMO C++ despite its warts is easier to avoid mismanaging memory than C. RAII and smart pointers are very useful. Fewer off by one errors leading to buffer overflows as well in my experience due to things like iterators.


Rust is going to beat both of these languages.

I think looking at this as a battle is not helpful to understanding the situation. In order to supplant C/C++, Rust (and Rust programmers) will need to operate in harmony with the existing ecosystem for decades.

This interoperability means that Rust programmers will need to also be good C/C++ programmers. Its not a binary OR, its more like diffusion.

Just as an example, the primary (or earliest) use of Rust is in Firefox. But Firefox is still a C++ project.


Rust is bigger than C++?!

I mean i can hardly imagine any language being BIGGER (as in more language features) than C++ (except C++ 2030 standard ;)


You’ve obviously never looked at swift.


Only because it has a npm style library.

The biggest chunck of ISO C++ is describing the standard library.

Just wait Rust to get 40 years of language improvements, while you try to link 5 different epochs on the same executable.


No, not bigger. Maybe same order of magnitude though.


They're actually pretty different. C is a very simple language - it's probably possible to learn most of the important parts in a few days. C++ is a super-set of C, but it adds a ton of complexity. For instance, C++ templating itself is turing complete.


Friendly nit: c++ isn't strictly a super set of c, thought it is fairly close.


Interesting! Could you explain? What C features doesn't C++ have?


- C has its own syntax for generics

- C has broader support for designated initializers

- C allows implicitly casting void* to any other pointer type

- C has fewer keywords, e.g. you can use "friend" or "class" as identifier

- ...

Despite all this, it's true enough that one can easily write C code that also compiles as C++.


- C has its own syntax for generics

C has generics?


Nothing like C++ or Rust generics. C has _Generic (type-switch macro): https://en.cppreference.com/w/c/language/generic

Go into pointer qualifiers and const with _Generic and you'll see that it's a mess to do anything serious with it. But it's handy for type-generic math (tgmath.h style) and that's seems to be about it.


C++ is vastly more complex, meaning that it should tend to have more footguns, and it definitely does.

Simplicity is a feature, and one that C++ aggressively avoids.


Unlikely to happen, except couple of small niches. Rust is too hard to learn, compiles too slow, hard to interop with C, and less safe than VM-based languages.

P.S. According to hackernews filter bubble, Lisp should have killed Java decades ago.


I agree that it's unlikely to happen, but not for any of those reasons.

* Rust is no harder to learn well than C, as someone else has already commented.

* Rust compiling too slowly is just an attribute of its current implementation — there's nothing about the language itself that makes it any slower at compilation than, say, C++.

* C interop isn't hard at all in my experience. Do you have any particular complaints?

* it's no less safe than VM-based languages. In fact, given the guarantees it gives you wrt parallelism, I'd say it's more safe than most VM-based languages.


> * Rust compiling too slowly is just an attribute of its current implementation — there's nothing about the language itself that makes it any slower at compilation than, say, C++.

Two points here. One, a comparison to C++ is a little disingenuous because C++ is notorious for slow compile times already. Two, it’s not really accurate to say that Rusts compile time is an implementation detail. In fact, many times over the lifetime of Rust the Rust developers have traded off compile time for particular features that they wanted to add. Compare this to, say, Go, which refuses to add any feature without a serious consideration of compile time impact. Sure, the current implementation could be sped up - but it certainly wasn’t designed to be.


"Disingenuous" is a little mean. Maybe we just have different standards of compilation speed?

You're right — Rust could be a totally different language and get compile time speeds like Go. But that doesn't change the fact that much of the problems with Rust's compile times are a result of its packaging system and compiler, rather than intrinsic to the language.


Yeah my mistake. Disingenuous meant something different than I thought. “Unfair” perhaps, but I don’t think you have any hidden motives here ;-)


Rust is no harder to learn well than C, as someone else has already commented.

My experience is the opposite of this. Back when dinosaurs walked the earth, I moved from one system language (Ada) to C and, in a couple of months, I was writing device drivers. I have struggled with Rust on hobby projects for a few years and have given it up 3 times -- this is despite having 18 years of C++ experience.

I would not say that you are wrong, just that this statement about the learning curve is not true for everyone.


Would you mind going into more detail about what you found hard about learning Rust? I'm interested in a counter perspective as someone who hasn't learned it yet and has mostly only seen positive media about it.


Please don't let my negative experience put you off learning Rust -- its an important language and worth putting the effort in. I would recommend diving in and seeing if it works for you.

For informational purposes, this is what I still find difficult:

- The module system. It constantly catches me out.

- I think that I understand traits but struggle using libraries that have a lot of traits in the public interface.

- Error handling is nice but there are error handling libraries going in and out of fashion every few months. Which one do I use?

- Callbacks combined with the borrow checker.

- Complexity of idiomatic code such as state machines [1].

- The strict string handling. What about strings that should be UTF-8 but come over a network protocol?

- Combining async code with non-async code. Also, how do you write a library that does I/O and supports both sync and async?

- Iterators. I have some functional programming experience but I hit problems with iterators combined with the borrow checker.

[1] This example has just 3 states and is much simpler than most real world examples: https://hoverbear.org/blog/rust-state-machine-pattern/


Thanks, there are some good pain points there.

> - The strict string handling. What about strings that should be UTF-8 but come over a network protocol?

From your description, it looks like you're looking for String::{from_utf8,from_utf8_lossy,from_utf8_unchecked}[0], but I'm guessing you've seen those already, so I'm confused.

> - Combining async code with non-async code. Also, how do you write a library that does I/O and supports both sync and async?

I think you'll have to just duplicate the code, but I'd be happy to be proven wrong.

[0]: https://doc.rust-lang.org/std/string/struct.String.html#meth...


> there's nothing about the language itself that makes it slow to compile

https://pingcap.com/blog/rust-compilation-model-calamity

https://pingcap.com/blog/generics-and-compile-time-in-rust

> Do you have any particular complaints?

It's same issue as in C# and many others: someone has to write and support the bindings, which adds cost.

> it's no less safe than VM-based languages

In VM-based languages which don't use unsafe code, vulnerabilities like this are impossible by design: https://medium.com/@shnatsel/how-rusts-standard-library-was-...


> It's same issue as in C# and many others: someone has to write and support the bindings, which adds cost.

If C was on the table anyway then you can use bindgen to generate the bindings.

But yeah, safe/native-feeling bindings require someone to go through and annotate everything.

> In VM-based languages which don't use unsafe code, vulnerabilities like this are impossible by design:

The VM itself is still going to have unsafe code at some point.


> The VM itself is still going to have unsafe code at some point.

Smaller amount of the unsafe code which is audited, battle-tested, and not extensible by either user nor third-party library developers.


The same could be said of the standard libary vulnerability you linked. But for other code,

(a) that's why people use cargo-geiger.

(b) you're arguing about the very small number of virtual machines that don't give their users such escape hatches.


> https://pingcap.com/blog/rust-compilation-model-calamity

Most of those issues are either about the compiler (it generates a lot of LLVM IR, it's single-threaded), or apply equally well to C++ (monomorphization, macros, build scripts). Nothing significantly impacting compilation times is fundamental to the language afaict.

> It's same issue as in C# and many others: someone has to write and support the bindings, which adds cost.

True.

> In VM-based languages which don't use unsafe code

Since you've added that qualifier, sure, Rust would be less safe. But how many VMs don't have such escape hatches? JavaScript in the browser is the only one that comes to mind.

> vulnerabilities like this are impossible by design

I find this very hard to believe. Even if your VM has no unsafe code, its standard library is probably implemented in unsafe code, where vulnerabilities like this can definitely happen.


> Most of those issues

Some of these issues

> monomorphization

C++ language is equally bad, but there're well-known workarounds. If you don't abuse Alexandrescu-style, using compilation units, have sane architecture without God objects, it's often not too bad.

> macros

Not just any macros, macros who require multiple passes. C macros are single-pass and pretty efficient.

> build scripts

How that applies to C++?

> how many VMs don't have such escape hatches?

Java doesn't. In C# the hatch exists but can be reliably shut.

> its standard library is probably implemented in unsafe code

No, they don't.

http://www.docjar.com/html/api/java/util/ArrayList.java.html

https://source.dot.net/#System.Private.CoreLib/List.cs


> Java doesn't.

JNI, com.sun.misc.Unsafe, etc

> In C# the hatch exists but can be reliably shut.

P/Invoke?


Technically the unsafe escape hatches exist in those languages, but I think the point is that they are needed less. In Rust you need unsafe to implement some types of graphs, for example, which in GC languages are easy to do without any unsafety.

It's a tradeoff, of course: GC languages let you avoid unsafe code at the cost of doing GCs, which in some applications is an issue. Rust's stroke of genius is that it can avoid GCs while giving you almost all the safety of a GC language.

Overall I think it's safe (no pun intended) to say that Rust is significantly safer than C or C++, but slightly less safe than Java or C#. But of course both of those comparisons have lots of caveats and exceptions. And there are other factors than safety as well.


> JNI

It's so complicated practically no one uses it.

> P/Invoke?

Can be disabled at VM level. Environments like asp.net classic default to partial trust, this ensures vast majority of third-party libraries aren't using p/invoke nor unsafe.


Rust parallism guarantees are only applicable to threaded code and internal resources.

We have already learned to scale down from threads and go back to processes for security and stability reasons.

Here Rust doesn't help across IPC and data races of external resources.

One way that Rust compiles way slower than C++ is its Gentoo approach to libraries. With C++ I only compile my own code.


> One way that Rust compiles way slower than C++ is its Gentoo approach to libraries. With C++ I only compile my own code.

That's a very good point, and maybe I'm being needlessly pedantic by considering it a part of the current (and only) implementation rather than a fundamental part of the language.

> We have already learned to scale down from threads and go back to processes for security and stability reasons.

Who is "we"? I still see a lot of parallel code being written with threads or async/await, and Rust's ownership system gives additional safety in both cases.


The browser vendors for example.


Is it really the case they "have already learned to scale down from threads"? I'm obviously not well-versed in browser internals, but here's the very first sentence of "Threading and Tasks in Chrome":

> Chrome has a multi-process architecture and each process is heavily multi-threaded.

https://chromium.googlesource.com/chromium/src/+/master/docs...

Either way, I think browsers have a very specific scenario, where there isn't much interaction between the tabs, and they need to be well-isolated from each other. I don't think that's a good reason for everyone else to move away from threads.



> Rust parallism guarantees are only applicable to threaded code and internal resources.

No, it can apply for single threaded async stuff as well.

> One way that Rust compiles way slower than C++ is its Gentoo approach to libraries.

That's not true in at least two ways:

1. You can also produce shared libraries in rust, I know as we do so for some stuff.

2. C++ often has some much stuff in headers that you do not only compile your code..

Also, in my experience, the compile time is nonetheless (faster to slower):

1. C

2. Rust

3. C++

if one is doing a mid-sized or bigger project with lots of language features used.


Single threaded async is a special case of M:N threading model.

Shared libraries in Rust don't get distributed via cargo like Conan, vcpkg or OS package managers are capable of.

Too much C++ stuff in headers, yes that is a thing, specially in badly organized builds. Extern templates, incremental compilation and linking are also a thing, and VC++ already has experimental C++20 module support.

My dummy Gtk-rs test project to validate Rust improvements after each release takes 16 minutes currently on a core duo with 8 GB and SSD. The Gtkmm variant takes about 3 minutes, because it doesn't need to compile Gtk-rs on each compiler upgrade.


Genuinely curious about the last sentence and would like to learn more on the Gentoo approach. Could you please provide a link or a little more details?


By "the Gentoo approach", I think pjmlp is referring to the fact that Cargo crates are usually compiled from source for each project, rather than simply distributing binaries. See [the Wikipedia article for Gentoo](https://en.wikipedia.org/wiki/Gentoo_Linux):

> Unlike a binary software distribution, the source code is compiled locally according to the user's preferences and is often optimized for the specific type of computer.


C is only easy to learn if by "learn" you mean "getting something to compile". Learning it enough to write programs without malloc vulnerabilities is basically impossible.


True, yet Frama-C and MISRA-C do exist, and certified compilers, which Rust is yet to have.

To prove how hard it is to replace C, even Microsoft with its security speech and "we don't need C on Windows" has given up to market pressure.

The Azure Sphere device whose marketing message is all about secure IoT, uses C as its only language, despite endless requests for C++, Rust, C# support.

The new MSVC version will support C11 and C17, minus the C99 features that became optional in C11.

Language evangelism without market understanding doesn't go far.


The C based programs I use most are probably various databases (mysql, postgres, redis, sqlite etc) and the linux kernel. Certainly for the databases they have been rock solid. It's possible to crash them by running the server out of resources of course, but I have never had them outright crash with a malloc problem. The kernel has more bugs perhaps, but that too has been rather stable for me.

C might not be perfect but it's clearly perfectly possible to write stable and secure programs in them.


That's not a huge deal for 2 reasons.

1. Not all software is exposed to internets, or requires many 9-s in reliability like avionics. A videogame that crashes their hardware-virtualized compartment on 1 out of 100k consoles is not OK, but might be good enough in practice if the unlucky users are refunded.

2. We have higher-level languages which solve these vulnerabilities for acceptable performance cost, and even easier to learn than C.


Most video games do connect to the internet these days.


You are speaking of an industry whose game engines would be a giant unsafe block, given some of the current practices.


They run supervised (if you exploited a game, can't infect the OS), and they don't quite need the reliability.


> Rust is too hard to learn

Complaints about Rust's learning curve is something I really do not get.

Yes, it forces you do actually think of what you're doing, which most devs seem to consider a Bad Thing™, but in the mid to long run it helps one enormously and it's one of the first languages of the last 30 years which actually makes lots of things better as a whole, while not being in a walled closed ecosystem.

> compiles too slow

There's definitively room for improvement here, but honestly, it's way faster than most C++ projects, and the fact that I have native support for nicely separating stuff in sub crates or workspaces, which dramatically improve iterative compiling, makes this a non-issue as long as one does not dump everything together as a pig pile.

> hard to interop with C

This is just plain wrong, it's very easy to interop with C - we're doing so with some projects, among other a library interoperating with QEMU, where the rust stuff is async (using tokio) and we can nicely integrate this into the C code of QEMU. Automatic binding generation allows you to do this quickly, albeit not very idiomatic most of the time. But manual binding generation is seldom hard, either already done on more popular stuff or one time cost, which, if one knows the code they want to bind too (they should) is rather small.

> less safe than VM-based languages

Hardly so. One is much more exposed to dynamic runtime errors in those, GC is a PITA and the VM is normally not safer than the rust std lib, as most of it is written in safe rust already and is around, battle tested for up to 5 or even 10 years.


> Complaints about Rust's learning curve is something I really do not get.

I've been programming C++ for living since 2000, recently it's C++/17. I think I have good understanding how software works in general, including heap and ownership. Tried to use Rust a couple times for hobby project, failed for various reasons. I don't have issues picking other languages: VBScript, C#, Objective C, Python, Go had little to no learning curve.

Another evidence in this thread: https://news.ycombinator.com/item?id=24878434

> while not being in a walled closed ecosystem.

Wasn't always the case, but .NET is open, thanks to competition. Python always was.

> it's very easy to interop with C

It's equally easy and almost as efficient in C#. The issue with both, someone has to write and then support the bindings. This ain't hard but has costs, while languages like C++ or Objective-C can directly consume C libraries.


AFAIK Rust interops with C better than basically other other language other than C++.


Does it support pointers?

It seems this is only for shaders, but if that’s the case one has been able to use shaders with Rust via GLSL since forever.


wow looks so cool :D




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: