Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
FORMUS3IC_LAS3
/
embb
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
1ed7535d
authored
Feb 18, 2015
by
Tobias Fuchs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
algorithms_cpp: minimized amount of tasks spawned recursively in ForEach, Reduce, Scan.
parent
7a2f4425
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
61 additions
and
49 deletions
+61
-49
algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h
+26
-18
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
+2
-2
algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h
+23
-15
algorithms_cpp/include/embb/algorithms/internal/scan-inl.h
+10
-14
No files found.
algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h
View file @
1ed7535d
...
...
@@ -41,6 +41,8 @@ namespace internal {
template
<
typename
RAI
,
typename
Function
>
class
ForEachFunctor
{
private
:
typedef
ForEachFunctor
<
RAI
,
Function
>
self_t
;
public
:
/**
* Constructs a for-each functor with arguments.
...
...
@@ -51,29 +53,33 @@ class ForEachFunctor {
block_size_
(
block_size
)
{
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
context
)
{
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
if
(
distance
==
0
)
return
;
if
(
distance
<=
block_size_
)
{
// leaf case -> do work
for
(
RAI
curIter
(
first_
);
curIter
!=
last_
;
++
curIter
)
{
unary_
(
*
curIter
);
for
(
RAI
it
=
first_
;
it
!=
last_
;
++
it
)
{
unary_
(
*
it
);
}
}
else
{
// recurse further
ChunkPartitioner
<
RAI
>
partitioner
(
first_
,
last_
,
2
);
ForEachFunctor
<
RAI
,
Function
>
functorL
(
partitioner
[
0
].
GetFirst
(),
partitioner
[
0
].
GetLast
(),
unary_
,
policy_
,
block_size_
);
ForEachFunctor
<
RAI
,
Function
>
functorR
(
partitioner
[
1
].
GetFirst
(),
partitioner
[
1
].
GetLast
(),
unary_
,
policy_
,
block_size_
);
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Task
taskL
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functorL
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
ChunkDescriptor
<
RAI
>
chunk_l
=
partitioner
[
0
];
ChunkDescriptor
<
RAI
>
chunk_r
=
partitioner
[
1
];
self_t
functor_l
(
chunk_l
.
GetFirst
(),
chunk_l
.
GetLast
(),
unary_
,
policy_
,
block_size_
);
self_t
functor_r
(
chunk_r
.
GetFirst
(),
chunk_r
.
GetLast
(),
unary_
,
policy_
,
block_size_
);
// Spawn tasks for right partition first:
mtapi
::
Task
task_r
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
policy_
));
mtapi
::
Task
taskR
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functorR
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
policy_
));
taskL
.
Wait
(
MTAPI_INFINITE
);
taskR
.
Wait
(
MTAPI_INFINITE
);
// Recurse on left partition:
functor_l
.
Action
(
context
);
// Wait for tasks on right partition to complete:
task_r
.
Wait
(
MTAPI_INFINITE
);
}
}
...
...
@@ -95,7 +101,9 @@ void ForEachRecursive(RAI first, RAI last, Function unary,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
difference_type
distance
=
std
::
distance
(
first
,
last
);
assert
(
distance
>
0
);
if
(
distance
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Distance for ForEach is 0"
);
}
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
// Determine actually used block size
if
(
block_size
==
0
)
{
...
...
@@ -127,7 +135,7 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary,
}
// namespace internal
template
<
typename
RAI
,
typename
Function
>
void
ForEach
(
RAI
first
,
RAI
last
,
Function
unary
,
void
ForEach
(
RAI
first
,
const
RAI
last
,
Function
unary
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typename
std
::
iterator_traits
<
RAI
>::
iterator_category
category
;
internal
::
ForEachIteratorCheck
(
first
,
last
,
unary
,
policy
,
block_size
,
...
...
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
View file @
1ed7535d
...
...
@@ -71,8 +71,8 @@ const ChunkDescriptor<ForwardIterator>
ForwardIterator
last_new
=
first_new
;
if
(
index
==
elements_count
/
chunkSize
)
{
std
::
advance
(
last_new
,
elements_count
%
chunkSize
)
;
if
(
index
>=
chunks
-
1
)
{
last_new
=
last
;
}
else
{
std
::
advance
(
last_new
,
chunkSize
);
}
...
...
algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h
View file @
1ed7535d
...
...
@@ -53,7 +53,7 @@ class ReduceFunctor {
block_size_
(
block_size
),
result_
(
result
)
{
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
context
)
{
if
(
first_
==
last_
)
{
return
;
}
...
...
@@ -66,22 +66,26 @@ class ReduceFunctor {
result_
=
result
;
}
else
{
// recurse further
internal
::
ChunkPartitioner
<
RAI
>
partitioner
(
first_
,
last_
,
2
);
ChunkDescriptor
<
RAI
>
chunk_l
=
partitioner
[
0
];
ChunkDescriptor
<
RAI
>
chunk_r
=
partitioner
[
1
];
ReturnType
result_l
(
neutral_
);
ReturnType
result_r
(
neutral_
);
ReduceFunctor
functor_l
(
partitioner
[
0
]
.
GetFirst
(),
partitioner
[
0
]
.
GetLast
(),
ReduceFunctor
functor_l
(
chunk_l
.
GetFirst
(),
chunk_l
.
GetLast
(),
neutral_
,
reduction_
,
transformation_
,
policy_
,
block_size_
,
result_l
);
ReduceFunctor
functor_r
(
partitioner
[
1
]
.
GetFirst
(),
partitioner
[
1
]
.
GetLast
(),
ReduceFunctor
functor_r
(
chunk_r
.
GetFirst
(),
chunk_r
.
GetLast
(),
neutral_
,
reduction_
,
transformation_
,
policy_
,
block_size_
,
result_r
);
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Task
task_l
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_l
,
&
ReduceFunctor
::
Action
),
policy_
));
mtapi
::
Task
task_r
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ReduceFunctor
::
Action
),
policy_
));
task_l
.
Wait
(
MTAPI_INFINITE
);
// Spawn tasks for right partition first:
mtapi
::
Task
task_r
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ReduceFunctor
::
Action
),
policy_
));
// Recurse on left partition:
functor_l
.
Action
(
context
);
// Wait for tasks on right partition to complete:
task_r
.
Wait
(
MTAPI_INFINITE
);
result_
=
reduction_
(
result_l
,
result_r
);
}
...
...
@@ -97,6 +101,9 @@ class ReduceFunctor {
size_t
block_size_
;
ReturnType
&
result_
;
/**
* Disables assignment and copy-construction.
*/
ReduceFunctor
&
operator
=
(
const
ReduceFunctor
&
);
ReduceFunctor
(
const
ReduceFunctor
&
);
};
...
...
@@ -110,21 +117,22 @@ ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral,
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
difference_type
distance
=
std
::
distance
(
first
,
last
);
assert
(
distance
>
0
);
if
(
distance
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Distance for Reduce is 0"
);
}
// Determine actually used block size
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
size_t
used_block_size
=
block_size
;
if
(
used_block_size
==
0
)
{
used_block_size
=
static_cast
<
size_t
>
(
distance
)
/
node
.
GetCoreCount
();
if
(
used_block_size
==
0
)
used_block_size
=
1
;
}
// Perform check of task number sufficiency
if
(((
distance
/
used_block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Number of computation tasks required in reduction would "
"exceed MTAPI maximum number of tasks"
);
}
ReturnType
result
=
neutral
;
typedef
ReduceFunctor
<
RAI
,
ReturnType
,
ReductionFunction
,
TransformationFunction
>
Functor
;
...
...
algorithms_cpp/include/embb/algorithms/internal/scan-inl.h
View file @
1ed7535d
...
...
@@ -54,7 +54,7 @@ class ScanFunctor {
node_id_
(
node_id
),
parent_value_
(
neutral
),
is_first_pass_
(
going_down
)
{
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
context
)
{
if
(
first_
==
last_
)
{
return
;
}
...
...
@@ -67,23 +67,19 @@ class ScanFunctor {
*
iter_out
=
result
;
++
iter_in
;
++
iter_out
;
while
(
iter_in
!=
last_
)
{
for
(;
iter_in
!=
last_
;
++
iter_in
,
++
iter_out
)
{
result
=
scan_
(
result
,
transformation_
(
*
iter_in
));
*
iter_out
=
result
;
++
iter_in
;
++
iter_out
;
}
SetTreeValue
(
result
);
}
else
{
// Second pass
RAIIn
iter_in
=
first_
;
RAIOut
iter_out
=
output_iterator_
;
while
(
iter_in
!=
last_
)
{
for
(;
iter_in
!=
last_
;
++
iter_in
,
++
iter_out
)
{
*
iter_out
=
scan_
(
parent_value_
,
*
iter_out
);
++
iter_in
;
++
iter_out
;
}
}
}
else
{
}
else
{
// recurse further
internal
::
ChunkPartitioner
<
RAIIn
>
partitioner
(
first_
,
last_
,
2
);
ScanFunctor
functor_l
(
partitioner
[
0
].
GetFirst
(),
partitioner
[
0
].
GetLast
(),
output_iterator_
,
neutral_
,
scan_
,
transformation_
,
...
...
@@ -102,13 +98,13 @@ class ScanFunctor {
functor_r
.
parent_value_
=
functor_l
.
GetTreeValue
()
+
parent_value_
;
}
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Task
task_l
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_l
,
&
ScanFunctor
::
Action
),
// Spawn tasks for right partition first:
mtapi
::
Task
task_r
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ScanFunctor
::
Action
),
policy_
));
mtapi
::
Task
task_r
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ScanFunctor
::
Action
),
policy_
));
task_l
.
Wait
(
MTAPI_INFINITE
);
// Recurse on left partition:
functor_l
.
Action
(
context
);
// Wait for tasks on right partition to complete:
task_r
.
Wait
(
MTAPI_INFINITE
);
SetTreeValue
(
scan_
(
functor_l
.
GetTreeValue
(),
functor_r
.
GetTreeValue
()));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment