- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Possible hypothesis:
Your priority queues are exhibiting a "sticky" property. Meaning, once queue at priority x starts, it runs until all entries at that priority are consumed. As a quick-and-dirty test for this, enqueue 10 low, then 10 normal, then 10 high (your 30 tasks). Then switch the orders of the 10's (normal,low,high; normal, high, low; high, now, normal; high, normal, low). "sticky" would result in the first enqueues first.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This may mean that once any low level task begins, all currently remaining low level tasks will run (via the first one run).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
using namespace System;using namespace std;
//I execute CreateTask.execute() which in turn creates the other 30 tasks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some required changes were obvious, but does your compiler really accept "tbb::priority_t::priority_normal"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have you considered using multiple concurrent queues, one for each priority. These queues can hold your own task functors w/wo arg(s). And your top-level task poll the queues in priority order. While this may not be energy efficient, it may provide you with the prioritization you seek (at least until you get a resolution on your task priority query).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some required changes were obvious, but does your compiler really accept "tbb::priority_t::priority_normal"?
I'm currently testing a Test-Case #1 andI don't think that an issue is related to this. It looks like TBB uses a
'LIFO' approach when executing created tasks but I can bewrong here. I'm still investigating.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On a Windows platforma modified Test Case #1 is notworking. TBB v4.0 is used. I'll provide all technical details later.
Note: Expected correctoutput. Produced due to an error in a Test-Case
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Guys,
I'm really sorry but I confirm a problem on a 32-bit Windows platform. I had anerror in my Test-Case and
it produced a correct output. I've updated a Post #13 andadded a note forthe screenshot:
"Note: Expected correctoutput. Produced due to an error in a Test-Case"
So, no matter what I tried to do tasks with 'normal' priorities are executed first, followed by 'high' and 'low' priorities.
Here are ALLtechnical details:
- Summary: Tasks with priority 'normal' ( enum value 1073741822 ) are executed first. Since on MacOS
tasks with priority 'high' are executed first I could assume that there is a portability issue
but so farit is not clear what is wrong. Enum values for prioritiesare as follows:
low = 536870911
normal = 1073741822
high = 1610612733
Since all objects of CMyTask are saved in some container it would be nice to find a way of
sorting the containerby priorities of tasksin descending order and thentorun
Test-Cases.
- OS: 32-bit Windows XP SP3
- TBB: version 4.0
tbb_stddef.h
...
#define TBB_VERSION_MAJOR 4
#define TBB_VERSION_MINOR 0
...
- IDE: MS Visual Studio 2005
- MS C/C++ compiler warning
...
tbb::task::enqueue( task01, tbb::priority_t::priority_low );
...
Warning C4482: nonstandard extension used: enum 'tbb::priority_t' used in qualified name
It is not related to the problem.
- There is an interesting comment in 'arena.h' header file:
struct arena_base : intrusive_list_node
{
...
//! Highest priority level containing enqueued tasks
/** It being greater than 0 means that high priority enqueued tasks had to be
bypassed because all workers were blocked in nested dispatch loops and
were unable to progress at then current priority level. **/
tbb::atomic
...
};
- Test-Cases Outputs:
// Test-Case 1
...
[ Task Number 012 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 002 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 022 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 023 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 013 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 003 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 001 ] [ Priority Code: low ] [ Priority: 536870911 ]
[ Task Number 021 ] [ Priority Code: low ] [ Priority: 536870911 ]
[ Task Number 011 ] [ Priority Code: low ] [ Priority: 536870911 ]
...
// Test-Case 2
...
[ Task Number 032 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 002 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 062 ] [ Priority Code: normal ] [ Priority: 1073741822 ]
[ Task Number 062 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 032 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 002 ] [ Priority Code: high ] [ Priority: 1610612733 ]
[ Task Number 001 ] [ Priority Code: low ] [ Priority: 536870911 ]
[ Task Number 061 ] [ Priority Code: low ] [ Priority: 536870911 ]
[ Task Number 031 ] [ Priority Code: low ] [ Priority: 536870911 ]
...
C/C++ codes for Test-Cases are in thenext post.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
class CMyTask : public tbb::task
{
public :
CMyTask()
{
};
CMyTask( int iNumber, char *szPriorityCode )
{
m_iNumber = iNumber;
strcpy( m_szPriorityCode, szPriorityCode );
m_iPriority = -1;
};
~CMyTask()
{
};
tbb::task * execute()
{
printf( "[ Task Number %03ld ] [ Priority Code: %6s ] [ Priority: %10ld ]\n",
( int )m_iNumber, &m_szPriorityCode[0], ( int )m_iPriority );
return ( tbb::task * )NULL;
};
void SetPriority( int iPriority )
{
m_iPriority = iPriority;
};
private:
int m_iNumber;
char m_szPriorityCode[16];
int m_iPriority;
};
void main( void )
{
printf( "Initialization started\n" );
#if defined ( __TBB_TASK_PRIORITY )
printf( "TBB Task Priorities Enabled\n" );
#else
printf( "TBB Task Priorities Disabled\n" );
#endif
// Test-Case SK1
///*
for( int i = 0; i < 3; i++ )
{
CMyTask &TaskL = *new( tbb::task::allocate_root() ) CMyTask( i*10+1, "low" );
TaskL.SetPriority( ( int )tbb::priority_t::priority_low );
tbb::task::enqueue( TaskL, tbb::priority_t::priority_low );
CMyTask &TaskN = *new( tbb::task::allocate_root() ) CMyTask( i*10+2, "normal" );
TaskN.SetPriority( ( int )tbb::priority_t::priority_normal );
tbb::task::enqueue( TaskN, tbb::priority_t::priority_normal );
CMyTask &TaskH = *new( tbb::task::allocate_root() ) CMyTask( i*10+3, "high" );
TaskH.SetPriority( ( int )tbb::priority_t::priority_high );
tbb::task::enqueue( TaskH, tbb::priority_t::priority_high );
}
//*/
// Test-Case SK2
///*
CMyTask *pTask[9] = {NULL };
for( int i = 0; i < 9; i += 3 )
{
pTask[i ] = new( tbb::task::allocate_root() ) CMyTask( i*10+1, "low" );
pTask[i ]->SetPriority( ( int )tbb::priority_t::priority_low );
tbb::task::enqueue( *pTask[i ], tbb::priority_t::priority_low );
pTask[i+1] = new( tbb::task::allocate_root() ) CMyTask( i*10+2, "normal" );
pTask[i+1]->SetPriority( ( int )tbb::priority_t::priority_normal );
tbb::task::enqueue( *pTask[i+1], tbb::priority_t::priority_normal );
pTask[i+2] = new( tbb::task::allocate_root() ) CMyTask( i*10+2, "high" );
pTask[i+2]->SetPriority( ( int )tbb::priority_t::priority_high );
tbb::task::enqueue( *pTask[i+2], tbb::priority_t::priority_high );
}
//*/
printf( "Initialization completed\n" );
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> tasks with priority 'high' are executed first I could assume that there is a portability issue
>> but so farit is not clear what is wrong. Enum values for prioritiesare as follows:
>> low = 536870911
>> normal = 1073741822
>> high = 1610612733
>> Since all objects of CMyTask are saved in some container it would be nice to find a way of
>>sorting the containerby priorities of tasksin descending order and thentorun
>> Test-Cases.
Hi Anton,
What do you think? I'm not absolutely confident in some portability issuebut it is clear that on different
OSs thereis adifferent execution order of tasks.
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some required changes were obvious, but does your compiler really accept "tbb::priority_t::priority_normal"?
I'm currently testing a Test-Case #1 andI don't think that an issue is related to this. It looks like TBB uses a
'LIFO' approach when executing created tasks but I can bewrong here. I'm still investigating.
Regarding 'LIFO' - my assumption is wrong. Tasks with 'normal' priorities are always executed first on a
Windows platform.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[SergeyK] It looks like this is a feature of the TBB library anda confirmation\explanation is needed.
We are working to fix other issues also related to the priorities in the scheduler, and will take this one into account of course.
[SergeyK] Please take a look at my "workaround" and correct me if I'm wrong because too much
"fuzzy" C/C++ codes in the TBB.I couldn't look everywhere andI don't know if it could
affect something else.
Here is a "workaround":
scheduler_common.h
...
static const intptr_t num_priority_levels = 3;
// static const intptr_t normalized_normal_priority = (num_priority_levels - 1) / 2;
static const intptr_t normalized_normal_priority = 2;// priority_high
...
A variable 'normalized_normal_priority' by default was initialized to '1':
( 3 - 1 ) / 2 = 1 and it corresponds to 'normal' priority
In my "workaround" I've changed the variable in the sources and then I've re-built the TBB library.
A runtime modificationis also possible, for example, with some global function or with a simplemodification
of the variable ( don't forget that it has a 'const' specificator).
ATest-Case SK1 produces that output on my development computer. Tryto "play" with the "workaround"
in order to confirm that it works on your computer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page