How can I control the number of threads? - raku

#The #url.elems >= 10000
for #url -> $url {
start {
say $url;
sleep(1);
}
}
How can I control the number of threads?

Before answering the question: the code you show loses the Promise returned by start. You probably want:
await do for #url -> $url {
start {
say $url;
sleep(1);
}
}
This will wait until all of the start blocks have completed.
To get back to your question: the environment variable RAKUDO_MAX_THREADS can be set before running your program to the maximum number of threads that will be created (default is 16).
Another approach that also works at runtime is to create a new ThreadPoolScheduler object dynamically:
my $*SCHEDULER = ThreadPoolScheduler.new(max_threads => 32);
Any threaded code that can see this version of $*SCHEDULER will now use this scheduler which has 32 threads available.

If you have a bunch of jobs in an array and want to work through them in parallel, take a look at hyper and race. (Currently marked as 'experimental', they will work even better in the next major release.)
With them, you can (potentially) control the parallelism with the 'batch' and 'degree' parameters.
#url.race(:batch(1),:degree(4)).map(-> $url {
say $url;
sleep(1);
});
They are, of course, subject to the overall thread limits of the ThreadPoolScheduler.

Related

What is "await do" in Perl 6?

I see the following code in Perl 6:
await do for #files -> $file {
start {
#do something ... }
}
which runs in async mode.
Why does the above code need do? What is the purpose of do in PerlĀ 6? Could someone please explain the above code in detail?
Also is there are an option to write something like this:
for #files -> $file {
start {
#do something ... }
}
and await after the code for the promises to be fulfilled?
The purpose of do
The for keyword can be used in two different ways:
1) As a stand-alone block statement:
for 1..5 { say $_ }
2) As a statement modifier appended to the end of a statement:
say $_ for 1..5;
When the bare for keyword is encountered in the middle of a larger statement, it is interpreted as that second form.
If you want to use the block form inside a larger statement (e.g. as the argument to the await function), you have to prefix it with do to tell the parser that you're starting a block statement here, and want its return value.
More generally, do makes sure that what follows it is parsed using the same rules it would be parsed as if it were its own statement, and causes it to provide a return value. It thus allows us to use any statement as an expression inside a larger statement. do if, do while, etc. all work the same way.
Explanation of your code
The code you showed...
await do for #files -> $file {
start {
#do somthing ... }
}
...does the following:
It loops of over the array #files.
For each iteration, it uses the start keyword to schedule an asynchronous task, which presumably does something with the current element $file. (The $*SCHEDULER variable decides how the task is actually started; by default it uses a simple thread pool scheduler.)
Each invocation of start immediately returns a Promise that will be updated when the asynchronous task has completed.
The do for collects a sequence of all the return values of the loop body (i.e. the promises).
The await function accepts this sequence as its argument, and waits until all the promises have completed.
How to "await after the code"
Not entirely sure what you mean here.
If you want to remember the promises but not await them just jet, simply store them in an array:
my #promises = do for #files -> $file {
start {
#do something ... }
}
#other code ...
await #promises;
There is no convenience functionality for awaiting all scheduled/running tasks. You always have to keep track of the promises.

How to limit JProfiler to a subtree

I have a method called com.acmesoftware.shared.AbstractDerrivedBean.getDerivedUniqueId(). When I JProfiler the application, this method, getDerivedUniqueId(), is essentially buried 80 methods deep as expected. The method is invoked on behalf of every bean in the application. I'm trying to record CPU calltree starting with this method down to leaf node (ie, one of the excluded classes).
I tried the following but it didn't produce the expected outcome:
Find a method above the method targeted for profiling, eg, markForDeletion().
set trigger to start recording at getDerivedUniqueId()
set trigger to STOP recording at markForDeletion()
I was expecting to only see everything below markForDeletion(), but I saw everything up to but not INCLUDING getDerivedUniqueId(), which is the opposite of my intended goal. Worse yet, even with 5ms sampling, this trigger increased the previous running time from 10 minutes to "I terminated after 3 hours of running". It seems the trigger is adding a giant amount of overhead on top of the overhead. Hence, even if I figure out how to correctly enable the trigger, the added overhead would seem to render it ineffective.
The reason I need to limit the recording to just this method is: When running in 5ms sampling mode, the application completes in 10 minutes. When I run it in full instrumentation, I've waited 3 hours and it still hasn't completed. Hence, I need to turn on full instrumentation ONLY after getDerivedUniqueId() is invoked and pause profiling when getDerivedUniqueId() is exited.
-- Updated/Edit:
Thank you Ingo Kegel for your assistance.
I am likely not clear on how to use triggers. In the code below, I set triggers as shown after the code. My expectation is that when I JProfile the application (both sampling and full instrumentation) with the below configured triggers, if boolean isCollectMetrics is false, I should see 100% or 99.9% of cpu in filtered classes. However, that is not the case. The CPU tree seems not to take into account the triggers.
Secondly, when isCollectMetrics is true, the jprofiler call tree I expect would start with startProfiling() and end at stopProfiling(). Again, this is not the case either.
The method contains() is the bottleneck. It eventually calls one of 150 getDerivedUniqueId(). I am trying to pinpoint which getDerivedUniqueId() is causing the performance degradation.
public static final AtomicLong doEqualContentTime = new AtomicLong();
public static final AtomicLong instCount = new AtomicLong();
protected boolean contentsEqual(final InstanceSetValue that) {
if (isCollectMetrics) {
// initialization code removed for clarity
// ..........
// ..........
final Set<Instance> c1 = getReferences();
final Set<Instance> c2 = that.getReferences();
long st = startProfiling(); /// <------- start here
for (final Instance inst : c1) {
instCount.incrementAndGet();
if (!c2.contains(inst)) {
long et = stopProfiling(); /// <------- stop here
doEqualContentTime.addAndGet(et - st);
return false;
}
}
long et = stopProfiling(); /// <------- stop here
doEqualContentTime.addAndGet(et - st);
return true;
} else {
// same code path as above but w/o the profiling. code removed for bravity.
// ......
// ......
return true;
}
}
public long startProfiling() {
return System.nanoTime();
}
public long stopProfiling() {
return System.nanoTime();
}
public static void reset() {
doEqualContentTime.set(0);
instCount.set(0);
}
The enabled triggers:
startProfiling trigger:
stopProfiling trigger:
I've tried 'Start Recordings' or 'Record CPU' buttons separately to capture the call tree only
If the overhead with instrumentation is large, you should refine your filters. With good filters, the instrumentation overhead can be very small,
As for the trigger setup, the correct actions are:
"Start recording" with CPU data selected
"Wait for the event to finish"
"Stop recording" with CPU data selected

How do I fix yield not working in while loop?

I get no console errors, but all of them isntantiate at the same time, so they are all one unit, and I want a delay between their spawn. (they are enemies traveling a path)
#pragma strict
// Instantiate a rigidbody then set the velocity
var projectile : Transform;
var cnt : int = 0;
function Update () {
if (buttonFeatures.started) {
while (cnt < 4) {
// Instantiate the projectile at the position and rotation of this transform
wait();
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation);
cnt++;
}
}
}
function wait(){
yield WaitForSeconds (10);
}
Your problem is you're trying to something similar to yield from Update(), which can't be done.
You can't obviously block Update() for 10 seconds, but calling a method that usesyield will return *immediately *and start a coroutine with that method, so what you're seeing is:
Update calls wait()
Update keeps going without waiting for wait() to return
wait() starts waiting for 10 seconds on it's own as a coroutine
Update continues through the loop, calling wait() 3 more times, not waiting each time.
To confirm this you can change wait():
function wait(){
yield WaitForSeconds (10);
Debug.Log("Done Waiting"); //You'll see 3 of these pop up in your console in 10 seconds later
}
You have two main options here. Either replace wait() with your logic:
function Update () {
if (buttonFeatures.started) {
while (cnt < 4) {
InstantiateProjectile(cnt*10)// Instantiate the projectile at the position and rotation of this transform in X seconds. This will return immediately
cnt++;
}
}
}
function InstantiateProjectile(delay : int){
yield WaitForSeconds(delay);
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation);
}
Or start a co-routine in Start():
function Start(){
UpdateProjectiles();
}
function UpdateProjectiles (){
while(true){
if (buttonFeatures.started) {
while (cnt < 4) {
yield WaitForSeconds (10); //This works because it's not in Update
var clone : Transform;
clone = Instantiate(projectile, transform.position, transform.rotation); // Instantiate the projectile at the position and rotation of this transform
cnt++;
}
}
yield; //This causes this coroutine to behave the way Update would (running once a frame)
}
}
The while(true) in the second example might be a little alarming, but it's performance is no different than using Update() because of the yield. In fact, many people use the majority of their "traditional" Update() logic in co-routines, as they allow better encapsulation of state management logic, and are great for periodic tasks.
Note: I didn't want to distort your code too much and obscure it's meaning, but you might want to reconsider certain parts of your code:
You have a while loop with a count, that can easily be a for loop.
You have a loop that seems to be replacing objects. Instantiate can be one of the most expensive calls you can make, because for every call you make to it, eventually you'll pay the cost of the GC cleaning up an object.
You don't want to be destroying lots of objects and calling Instantiate to replace them with identical ones, because the GC will start slowing your game to a standstill keeping up. Right now as your code stands, if projectiles start being spawned in a situation where they're being destroyed very quickly, I won't be surprised if the game completely freezes.
Instead, prefer reusing objects, with object pools. There are tutorials on how to do it, such as this one. At the most basic level, it can be something as simple as giving your projectiles a Reset method. Then you could replace Destroy with a method that calls Reset and stores them in a Stack or List, where they can be accessed again. But you'll want to encapsulate all that logic, so look at that tutorial for specifics.
replace this line instead of making the function call:
yield return new WaitForSeconds(10);

Asynchronously start only one Task to process a static Queue, stopping when it's done

Basically I have a static custom queue of objects I want to process. From multiple threads, I need to kick off a singular Task that will process the queued objects, stopping the task when all items are dequeued.
Some psuedo code:
static CustomQueue _customqueue;
static Task _processQueuedItems;
public static void EnqueueSomething(object something) {
_customqueue.Enqueue(something);
StartProcessingQueue();
}
static void StartProcessingQueue() {
if(_processQueuedItems != null) {
_processQueuedItems = new Task(() => {
while(_customqueue.Any()) {
var stuffToDequeue = _customqueue.Dequeue();
/* do stuff */
}
});
_processQueuedItems.Start();
}
if(_processQueuedItems.Status != TaskStatus.Running) {
_processQueuedItems.Start();
}
}
If it makes a difference my custom queue is a queue that essentially holds items until they reach a certain age, then allows them to dequeue. Everytime an item is touched its timer starts again. I know this piece works fine.
The part I'm struggling with is the parallelism. (Clearly, I don't know what I'm doing here). What I want is to have one thread process the queue until it's complete, then go away. If another call comes in it doesn't start a new thread unless it has to.
I hope that explains my issue okay.
You might want to consider using BlockingCollection<T> here. You could make your custom queue implement IProducerConsumerCollection, in which case BC could use it directly.
You'd then just need to start a long running Task to call blockingCollection.GetConsumingEnumerable() and process the items in a foreach. The task will automatically block when the collection is empty, and restart when a new item is Enqueued.

.NET 4.0 Threading.Tasks

I've recently started working on a new application which will utilize task parallelism. I have just begun writing a tasking framework, but have recently seen a number of posts on SO regarding the new System.Threading.Tasks namespace which may be useful to me (and I would rather use an existing framework than roll my own).
However looking over MSDN I haven't seen how / if, I can implement the functionality which I'm looking for:
Dependency on other tasks completing.
Able to wait on an unknown number of tasks preforming the same action (maybe wrapped in the same task object which is invoked multiple times)
Set maximum concurrent instances of a task since they use a shared resource there is no point running more than one at once
Hint at priority, or scheduler places tasks with lower maximum concurrent instances at a higher priority (so as to keep said resource in use as much as possible)
Edit ability to vary the priority of tasks which are preforming the same action (pretty poor example but, PredictWeather (Tommorrow) will have a higher priority than PredictWeather (NextWeek))
Can someone point me towards an example / tell me how I can achieve this? Cheers.
C# Use Case: (typed in SO so please for give any syntax errors / typos)
**note Do() / DoAfter() shouldn't block the calling thread*
class Application ()
{
Task LeafTask = new Task (LeafWork) {PriorityHint = High, MaxConcurrent = 1};
var Tree = new TaskTree (LeafTask);
Task TraverseTask = new Task (Tree.Traverse);
Task WorkTask = new Task (MoreWork);
Task RunTask = new Task (Run);
Object SharedLeafWorkObject = new Object ();
void Entry ()
{
RunTask.Do ();
RunTask.Join (); // Use this thread for task processing until all invocations of RunTask are complete
}
void Run(){
TraverseTask.Do ();
// Wait for TraverseTask to make sure all leaf tasks are invoked before waiting on them
WorkTask.DoAfter (new [] {TraverseTask, LeafTask});
if (running){
RunTask.DoAfter (WorkTask); // Keep at least one RunTask alive to prevent Join from 'unblocking'
}
else
{
TraverseTask.Join();
WorkTask.Join ();
}
}
void LeafWork (Object leaf){
lock (SharedLeafWorkObject) // Fake a shared resource
{
Thread.Sleep (200); // 'work'
}
}
void MoreWork ()
{
Thread.Sleep (2000); // this one takes a while
}
}
class TaskTreeNode<TItem>
{
Task LeafTask; // = Application::LeafTask
TItem Item;
void Traverse ()
{
if (isLeaf)
{
// LeafTask set in C-Tor or elsewhere
LeafTask.Do(this.Item);
//Edit
//LeafTask.Do(this.Item, this.Depth); // Deeper items get higher priority
return;
}
foreach (var child in this.children)
{
child.Traverse ();
}
}
}
There are numerous examples here:
http://code.msdn.microsoft.com/ParExtSamples
There's a great white paper which covers a lot of the details you mention above here:
"Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4"
http://www.microsoft.com/downloads/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-c1637026c3ee&displaylang=en
Off the top of my head I think you can do all the things you list in your question.
Dependencies etc: Task.WaitAll(Task[] tasks)
Scheduler: The library supports numerous options for limiting number of threads in use and supports providing your own scheduler. I would avoid altering the priority of threads if at all possible. This is likely to have negative impact on the scheduler, unless you provide your own.