| Summary: | [Jobs] Should run progress views and status lines with one update job | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Jerome Lanneluc <jerome_lanneluc> |
| Component: | UI | Assignee: | Tod Creasey <Tod_Creasey> |
| Status: | RESOLVED INVALID | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | john.arthorne |
| Version: | 3.0 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows 2000 | ||
| Whiteboard: | |||
| Bug Depends on: | 43841 | ||
| Bug Blocks: | |||
|
Description
Jerome Lanneluc
This is because the progress view updates every 100 ms and there will be a lot of updates if a lot of work is going on. These updates should be slowed down if the system is very busy. John is there a decent way to make this determination? We've had a few reports of responsiveness problems in the latest build, so I'm going to do some much need profiling this afternoon to see what I can turn up. I'd like to understand where the time is going before we do further tweaking. I have written a test that runs a seperate job for each file or directory entry in your Eclipse install - it usually hits close to 500 posted jobs at a time. The presence of the ProgressView appears to make no difference (in fact it was faster when the view was open but I think this doesn't really mean anything). Jerome can you give me an idea of the types of things going on in your workbench at a given time? I am not sure that we make that much difference but if there are expensive UI operations going on the updates could be a factor in process switching. I have found a place where I was synching during an update to the viewer in the progress view and I have refactored the synch to finish before the update occurs. This will be in build >20030929 but I am going to leave this PR open as I expect we may find more inprovements. I've done some profiling, and I haven't found anything in particular about the progress view that is bogging the system down. During a background task that reported 1,000,000 units of progress, the system was responsive and the progress view updated quickly. One thing to consider: the scheduling delay for the "updating progress" job is currently 100ms... this is the main thing that makes it responsive right now. I.e., on the job that reported 1,000,000 units of progress, the progress manager tried to schedule 1,000,000 UI jobs to update the progress view, but only a very small number actually got scheduled (one every 100ms). This is a good thing, but we could consider upping the 100ms delay to something greater, such as 250ms or even 500ms to get even more batching. This is not the cause of the problem, but I thought it worth point out:
profiling a job that just reports progress in a tight loop shows the largest
chunk of time is spent in JobProgressManager.refresh (I think this has been
renamed to ProgressManager in HEAD). Most of the time is spent in the overhead
of acquiring the object monitor (about 10% of total thread time).
In core, we use the "copy on write" pattern for situations like this. Assuming
that modifying the set of listeners is relatively rare, but traversal is very
common, you can do the following:
- On traversal, obtain a pointer to the array and iterate over that:
IJobProgressListener[] temp = this.listeners;
for (int i = 0; i < temp; i++)
temp[i].refresh(...)
- On modification, synchronize and copy the entire array:
synchronized (listeners) {
IJobProgressListener[] temp = this.listeners;
IJobProgressListener[] newList = new IJobProgressListener[temp.length+1];
System.arraycopy(temp, 0, newList, 0, temp.length);
newList[temp.length] = newListener;
this.listeners = newList; //atomic assignment
}
- the synch block when modifying the set of listeners is just to prevent
multiple concurrent changes to the listener list. It doesn't prevent concurrent
reads.
This is a fairly advanced optimization so I'm not sure if it's worth it at this
point, but something to keep in mind.
Tod, I have autobuild turned on, and all I do is incremental builds. If an incremental build takes a long time (e.g. change the value of a constant), while the builder compiles all the dependent of the changed file, the progress view updates with each package that is being recompiled. And while it is updating, I cannot even move the workbench windows (note that I have several windows open if it makes any difference). Also this is on Win2000. I'll try today's build and let you know if your change improves things. This was where my idea about being able to determine relative busyness of the job manager came in - jobs with DECORATE priority could have thier service time increased when loads are heavy. I now get the list of updates in the synch block but do the updates outside of it - I would be interested in seeing the difference with todays build. I have just checked in 20030930 and the responsiveness with the ProgressView appears to be fine in your case. I am going to close this PR - please reopen if you find a problem use case. Unfortunately, I can still see the problem in I20030930. I'll reopen the bug as soon as I find steps to reproduce. Jerome, how many workbench windows do you typically have open? I wonder if it only really starts to thrash when there are many workbench windows. Tod: is there a separate job to update the status line/progress view of each window? I wonder if this is the problem: five windows with two jobs per window (one status line and one progress view) is ten asyncExecs for each unit of progress. I can imagine this bringing the UI thread to its knees. Ideally a single job could update all status lines... Yes they are currently seperate jobs right now mostly because the progress view gets updated much more frequently. I want to avoid computation inside the job or worse yet in a synched part of the job - melding them together would make this much more prone to freezing. Ok, the status line and progress view can't be updated together then. How about a single job for the progress view, and a single job for all status line updates? This would be similar to our solution for the animation loop, where you collapsed one job per window down into a single job for all windows. Thats a good idea. Jerome how many windows do you run in I usually have 3 to 5 windows open. The fix for running the progress view with one updater is in build >20031006 Upgrading to P3 as there is now a problem where the status line is getting updated but the progress view isn't - we need to keep the timing consistent. What might be the best solution is to add the 3 UI based listeners (status, progress and indicator) to a single update job. Status line no longer shows updates. |