Vlad
And you have maybe 8 threads total
Vlad
They all coexist and are fine
Vlad
And no one blocks each other
~
We were talking about "blocking"
That is OS thread capability in CPU task. Our main problem is OS thread is IO task :)
Vlad
That is OS thread capability in CPU task. Our main problem is OS thread is IO task :)
You can implement the same threading without os threads on a single thread
Vlad
All it takes is some interrupts and while loops
Vlad
Also this is literally how node js works
~
You can implement the same threading without os threads on a single thread
That is green thread, it will not make CPU tasks paral, because green thread can not run by its own. OS thread execute each green thread task, green thread is just for releasing the OS thread when waiting for IO result
Vlad
OS threads are not magic
Vlad
You can implement them in userspace
Vlad
On a single thread
Vlad
Also any real world coroutine implementation will do scheduling
~
I mean if it is equivalent to goroutine, Java virtual thread, and async await. Then lets use single thread app for example The purpose of coroutine is to make IO task concurrent with single thread possible But spawning 2 coroutines in single thread context will not make the app able to execute 2 CPU task in paralel. The single threaded app will behave the same like when using OS thread directly without coroutine (executing CPU task in concurrent), coroutine just adds unnecerery complexity and overhead in CPU task
~
That is what I gained from goroutine, virtual thread, and async await understanding that is equal to coroutine as you said
~
You can implement them in userspace
That is green thread, just like goroutine and virtual thread that equal to async await, that are run on top of OS thread, like my description above
Ludovic 'Archivist'
I mean for example single threaded app. It does not matter how many coroutines you create, if that coroutine render a graphic for 5 minutes, the OS thread is blocked for 5 minutes, coroutine does not makes it concurrent or paralel for CPU task. Only multiple OS threads can
Well, of course if your task segmentation is non-sensical your time utilisation will be non sensical too. Why do you think the Erlang runtime prohibits loops for? Precisely task segmentation
Ludovic 'Archivist'
Sadly the C++ standard is not really friendly to that type of coding style, since tail recursion is not a guaranteed optimization
Mohd Ashar Khan
Do anyone has experience in Dual Booting Windows and Linux, here?
Rose
Do anyone has experience in Dual Booting Windows and Linux, here?
Offtopic discussions should be done in the C/C++ Offtopic group. Please take your discussion/questions there.
~
Well, of course if your task segmentation is non-sensical your time utilisation will be non sensical too. Why do you think the Erlang runtime prohibits loops for? Precisely task segmentation
I do not understand 😅 but the previous talk is about coroutine does not offer performance enhancement for CPU task at all, intead just add overhead. Where coroutine benefit is when doing IO task, it makes OS thread will not idle waiting for IO result. Because previously coroutine is said equal to goroutine, async await that also equal to java virtual thread and kotlin coroutine
~
This is a good simple article about kotlin coroutine https://medium.com/@arunb9525/coroutines-vs-threads-a-comprehensive-comparison-for-modern-programming-2a2a5f7ec533
Blue
How did you guys leaned to code
Damn this is a 3 year old msg. Feels like a time travel
Ludovic 'Archivist'
I do not understand 😅 but the previous talk is about coroutine does not offer performance enhancement for CPU task at all, intead just add overhead. Where coroutine benefit is when doing IO task, it makes OS thread will not idle waiting for IO result. Because previously coroutine is said equal to goroutine, async await that also equal to java virtual thread and kotlin coroutine
Currently C++ coroutines can or cannot run on several threads. So a blanket statement is most definitely incorrect. C++ coroutine can implement parallel processing but do not need to. You can absolutely implement a parallel algorithms with C++ coroutines that will be faster despite not having IO
布丁
C++ coroutines have some inherent overhead that is not suitable for CPU intensive tasks
布丁
e.g. each coroutine created involves memory allocation that is hard to be optimized out
~
Currently C++ coroutines can or cannot run on several threads. So a blanket statement is most definitely incorrect. C++ coroutine can implement parallel processing but do not need to. You can absolutely implement a parallel algorithms with C++ coroutines that will be faster despite not having IO
I mean did not say you can not. It just the same as running goroutines on top of multiple OS threads instead of single thread, the same apply to any simolar approach in other languages. But it does not make it more performant than using OS thread directly, instead it adds unnecerery overhead, note : CPU bound task like AI
~
Coroutine is meant for IO bound tasks
Ludovic 'Archivist'
Not all programs are single user. Server software is inherently multiuser, and segmenting tasks and fair scheduling of parallel loads that do require processing allows to limit latency spikes
~
No, but it allows, provided correct tasks segmentation, to spread several loads and tasks from several queries for example, to ensure all are making reasonable progress without blocking everyone
Umm I do not understand, is not you ca only have block if there is IO tasks? If it pure CPU task, the CPU will not idle, it will keep doing work
Ludovic 'Archivist'
Umm I do not understand, is not you ca only have block if there is IO tasks? If it pure CPU task, the CPU will not idle, it will keep doing work
If you run a parallel algorithm that will take 10 seconds on a server, no request can be processed during those 10 seconds. But if the parallel algorithm is segmented in smaller steps, even if it takes longer to run, it will leave fair time to process other queries fairly
Ludovic 'Archivist'
Coroutines make it easier to segment things like that
~
If you run a parallel algorithm that will take 10 seconds on a server, no request can be processed during those 10 seconds. But if the parallel algorithm is segmented in smaller steps, even if it takes longer to run, it will leave fair time to process other queries fairly
I do not think so, if it is pure CPU task, the OS thread context switch will execute all the CPU task in some duratiom and move to other continously until all finish You are mixing CPU and IO task (network socket is IO). That is my point, OS thread is only be blocked (not doing anything) when it is executing IO task, it waits IO result and do nothing in the waiting duration. This is where coroutine comes to play, coroutine allows the OS thread be freed to execute other task while waiting IO result
~
Do you start new threads for parallel tasks, personally I use a thread pool
I usually use OS thread for CPU tasks, equal to number of CPU cores, but sometimes higher
Ludovic 'Archivist'
I usually use OS thread for CPU tasks, equal to number of CPU cores, but sometimes higher
So you create a new thread every time your server receives a connection?
~
Only multiple OS thread offers true paralel execution of CPU computation in multi cores CPU
~
So you create a new thread every time your server receives a connection?
That is IO task, that is what coroutine is meant for
~
You keep mixing CPU computation task and IO task sir
Ludovic 'Archivist'
So if your query does number crunching, you will start an os thread for every query?
Ludovic 'Archivist'
For the application I am working with, with the number of users querying heavy calculations, that would mean around 10k OS threads at a time
布丁
thread pool. solved.
~
So if your query does number crunching, you will start an os thread for every query?
Not, accepting TCP socket connectipn is IO task, it is why I will use coroutines that run on top of 8 OS threads if I have 8 cores What I talk about is "pure CPU task no hing scale IO tasks involved" like running LLM model
~
You keep mixing CPU and IO task :<
Ludovic 'Archivist'
Why would you want to pay for context switches when you can use the same scheduler you use for your coroutines
~
Each of the requests I receive requires around a second of intensive linear algebra
If there is long running CPU computation is the request handler, I will spawn that computation code to thread pool dedicated for blocking operation, so my 8 os threads can run the coroutines to keep accepting new request
Ludovic 'Archivist'
Particularly knowing C++ coroutines are stalkless
~
Why would you want to pay for context switches when you can use the same scheduler you use for your coroutines
Coroutine does not enhance it, the one that execute is still OS thread behind it
Ludovic 'Archivist'
Coroutine does not enhance it, the one that execute is still OS thread behind it
Yes, but an os thread that doesn’t need starting, context switching, stack swapping or address space sanitising
Ludovic 'Archivist'
That is what coroutines bring you
~
And that is useless overhead if you already have a coroutines runner
No not, that is moving the long CPU computation to decicated thread pool to achieve true paralel. Because if you run it in coroutine, the OS thread that is meant to handlr accepting new request will be blocked
布丁
I thought it's a common sense in [any languages/runtimes with an async equivalent mechanism] not to block the worker threads no?
布丁
布丁
Are we talking about C++ coroutines?
Or all your augments above actually apply to something else?
~
Yes, but an os thread that doesn’t need starting, context switching, stack swapping or address space sanitising
No sir, coroutine is just function that will be executed by OS thread in the end of the day. If you allow the OS thread to execute coroutine that has long CPU computation task, the OS threads that are mean to keep accepting new request will be decreased from 8 to 7, until the CPU computation task finish, and the OS thread that executed said coroutine task rejoin the accepting new connection task by running new coroutine task. It is why the long CPU task is moved to dedicated thread pool, so that the 8 OS thread can keep happy picking new coroutine (new connection) to be executed
Ludovic 'Archivist'
Are we talking about C++ coroutines?
BEAM has the benefit of segmenting your coroutines for you. In C++ you are responsible for creating your own sequence points
Ludovic 'Archivist'
sir this is just irrelevant
No, it is, precisely, the point that I have been making. You can absolutely use coroutines outside of just IO tasks provided that your tasks are properly segmented
Ludovic 'Archivist'
And if you work with Erlang FFI that is implemented in C++, it is the preferred way to implement it nowadays
布丁
No, it is, precisely, the point that I have been making. You can absolutely use coroutines outside of just IO tasks provided that your tasks are properly segmented
Coroutines are just suspendable/resumable functions. It says nothing about the scheduler. The scheduler under the hood can be single-threaded.
Ludovic 'Archivist'
布丁
You implement the scheduler yourself in C++, it is parallel if you will it to be
I agree that a good multi-threaded scheduler is a must-have for efficient CPU-extensive tasks, but it has nothing to do with coroutines.
布丁
You are perfectly allowed to use a general-purpose multi-threaded scheduler without coroutines.
Ludovic 'Archivist'
Ludovic 'Archivist'
布丁
Without making the code of the processing more complicated
Applies only to those tasks that may suspend halfway, mostly IO
Ludovic 'Archivist'
Applies only to those tasks that may suspend halfway, mostly IO
What task may not suspend halfway (beyond cryptographic tasks)?
Ludovic 'Archivist'
Any CPU-bound tasks
Why can’t you suspend a CPU bound task?