4 ms·
MSVC's C++ Parallel algorithms library gets close [1], and so does Rust's Rayon crate [2]. C# has parallel for loops [3], and apparently so does PowerShell [4]
by yoshuaw 6y ago
MSVC's C++ Parallel algorithms library gets close [1], and so does Rust's Rayon crate [2]. C# has parallel for loops [3], and apparently so does PowerShell [4]
Though none of these are quite as convenient as I think they could be. I suspect there is a path for Rust to add parallel iteration syntax in the future [5]. There are quite a few steps needed to get there, but the result could look something like this:
let mut listener = TcpListener::bind("127.0.0.1:8080")?;
println!("Listening on {}", listener.local_addr()?);
par for stream? in listener.incoming() {
println!("Accepting from: {}", stream.peer_addr()?);
io::copy(&stream, &stream)?;
}
[1]: https://devblogs.microsoft.com/cppblog/using-c17-parallel-algorithms-for-better-performance/ https://devblogs.microsoft.com/cppblog/using-c17-parallel-al...
[2]: https://docs.rs/rayon/1.5.0/rayon/ https://docs.rs/rayon/1.5.0/rayon/
[3]: https://dotnettutorials.net/lesson/parallel-for-method-csharp/ https://dotnettutorials.net/lesson/parallel-for-method-cshar...
[4]: https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/ https://devblogs.microsoft.com/powershell/powershell-foreach...
[5]: https://blog.yoshuawuyts.com/parallel-stream/#future-directions https://blog.yoshuawuyts.com/parallel-stream/#future-directi...
- eptcyka 6y agoWhat'd be the concurrency primitive used in the parallel block? Is scheduling done per loop or globally? All of these questions are trivial if there's a runtime and become very cumbersome if the language has ambitions to be usable without any standard libraries.
- volta83 6y agoIf you use the standard library, its parallel run-time gets automatically linked. This is often the right choice when building binaries for a platform with an operating system, etc. If you do not include the standard library _AND_ if you use these features, then you'd need to provide your own parallel run-time or your application won't compile. There are many valid implementations of these run-times tuned for different applications, these run-times can be as simple or complex as you'd like, in some cases some run-times only work on particular bare metal targets, and in most cases you just pull a library with the implementation that you'd want to use. Since a valid implementation of the run-time is to just run all tasks sequentially, you can provide a tiny (often "zero-size") run-time for those environments on which code-size trumps everything. You can also provide the standard parallel run-time, but this might require operating-system like functionality, like thread, mutex, etc. support. If your embedded target does not provide those, you'd need to provide implementations of these yourself. The important thing is that you don't need to change any code that uses the run-time, e.g., all the app code can still use fork-join parallelism, but you control how that's executed by swapping the modular runtime component.
- yoshuaw 6y agoYes, exactly. Rust already allows for switching global allocators through `#[global_allocator]`. But now also allows plugging allocators inline through the allocator-api methods. I'd imagine something similar could be introduced for threadpools / runtimes.
- Someone 6y agoI don’t think you can do that well without some global state and code to handle it (aka ‘a runtime’). It’s not like separate parts of a program can each optimize for the number of threads and their memory for their goals. Optimization/tuning has to happen globally because the resources used (threads, memory) are shared between those parts. I think most solutions have some global state that magically decides how many threads to run in parallel (more for I/O bound code), how many to assign to each part (which don’t even have to be perfectly separate. Part P might parallellisme a loop where each iteration calls into part Q, which also runs a parallel loop. If each of these decides to run one thread per CPU for N threads in total, the result still c/would be that N² threads run in parallel, likely with suboptimal results)
- AtlasBarfed 6y agoI love GPars for Groovy, but unfortunately it isn't CompileStatic compatible or Groovy 3.0 compatible.