Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
predictable_parallel_patterns
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
68af3068
authored
5 years ago
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add divison strategies for for-each api.
parent
f3e7df77
Pipeline
#1307
failed with stages
in 25 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
13 deletions
+73
-13
lib/pls/include/pls/algorithms/for_each.h
+12
-0
lib/pls/include/pls/algorithms/for_each_impl.h
+59
-11
lib/pls/include/pls/algorithms/scan_impl.h
+2
-2
No files found.
lib/pls/include/pls/algorithms/for_each.h
View file @
68af3068
...
...
@@ -5,9 +5,21 @@
namespace
pls
{
namespace
algorithm
{
class
fixed_strategy
;
class
dynamic_strategy
;
template
<
typename
Function
,
typename
ExecutionStrategy
>
void
for_each_range
(
unsigned
long
first
,
unsigned
long
last
,
const
Function
&
function
,
ExecutionStrategy
&
execution_strategy
);
template
<
typename
Function
>
void
for_each_range
(
unsigned
long
first
,
unsigned
long
last
,
const
Function
&
function
);
template
<
typename
RandomIt
,
typename
Function
,
typename
ExecutionStrategy
>
void
for_each
(
RandomIt
first
,
RandomIt
last
,
const
Function
&
function
,
ExecutionStrategy
execution_strategy
);
template
<
typename
RandomIt
,
typename
Function
>
void
for_each
(
RandomIt
first
,
RandomIt
last
,
const
Function
&
function
);
...
...
This diff is collapsed.
Click to expand it.
lib/pls/include/pls/algorithms/for_each_impl.h
View file @
68af3068
...
...
@@ -4,6 +4,7 @@
#include "pls/internal/scheduling/task.h"
#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/thread_state.h"
#include "pls/internal/helpers/unique_id.h"
#include "pls/internal/helpers/range.h"
...
...
@@ -13,11 +14,10 @@ namespace algorithm {
namespace
internal
{
template
<
typename
RandomIt
,
typename
Function
>
void
for_each
(
RandomIt
first
,
RandomIt
last
,
const
Function
&
function
)
{
void
for_each
(
const
RandomIt
first
,
const
RandomIt
last
,
const
Function
function
,
const
long
min_elements
)
{
using
namespace
::
pls
::
internal
::
scheduling
;
constexpr
long
min_elements
=
1
;
// TODO: tune this value/allow for execution strategies
long
num_elements
=
std
::
distance
(
first
,
last
);
const
long
num_elements
=
std
::
distance
(
first
,
last
);
if
(
num_elements
<=
min_elements
)
{
// calculate last elements in loop to avoid overhead
for
(
auto
current
=
first
;
current
!=
last
;
current
++
)
{
...
...
@@ -25,15 +25,25 @@ void for_each(RandomIt first, RandomIt last, const Function &function) {
}
}
else
{
// Cut in half recursively
long
middle_index
=
num_elements
/
2
;
const
long
middle_index
=
num_elements
/
2
;
auto
second_half_body
=
[
first
,
middle_index
,
last
,
&
function
]
{
internal
::
for_each
(
first
+
middle_index
,
last
,
function
);
};
[
first
,
middle_index
,
last
,
&
function
,
min_elements
]
{
internal
::
for_each
(
first
+
middle_index
,
last
,
function
,
min_elements
);
};
using
second_half_t
=
lambda_task_by_reference
<
decltype
(
second_half_body
)
>
;
scheduler
::
spawn_child
<
second_half_t
>
(
std
::
move
(
second_half_body
));
auto
first_half_body
=
[
first
,
middle_index
,
last
,
&
function
]
{
internal
::
for_each
(
first
,
first
+
middle_index
,
function
);
};
[
first
,
middle_index
,
last
,
&
function
,
min_elements
]
{
internal
::
for_each
(
first
,
first
+
middle_index
,
function
,
min_elements
);
};
using
first_half_t
=
lambda_task_by_reference
<
decltype
(
first_half_body
)
>
;
scheduler
::
spawn_child_and_wait
<
first_half_t
>
(
std
::
move
(
first_half_body
));
}
...
...
@@ -41,15 +51,53 @@ void for_each(RandomIt first, RandomIt last, const Function &function) {
}
template
<
typename
Function
>
void
for_each_range
(
unsigned
long
first
,
unsigned
long
last
,
const
Function
&
function
)
{
auto
range
=
pls
::
internal
::
helpers
::
range
(
first
,
last
);
internal
::
for_each
(
range
.
begin
(),
range
.
end
(),
function
);
class
dynamic_strategy
{
public
:
explicit
dynamic_strategy
(
const
unsigned
int
tasks_per_thread
=
4
)
:
tasks_per_thread_
{
tasks_per_thread
}
{};
long
calculate_min_elements
(
long
num_elements
)
const
{
const
long
num_threads
=
pls
::
internal
::
scheduling
::
thread_state
::
get
()
->
scheduler_
->
num_threads
();
return
num_elements
/
(
num_threads
*
tasks_per_thread_
);
}
private
:
unsigned
const
int
tasks_per_thread_
;
};
class
fixed_strategy
{
public
:
explicit
fixed_strategy
(
const
long
min_elements_per_task
)
:
min_elements_per_task_
{
min_elements_per_task
}
{};
long
calculate_min_elements
(
long
/*num_elements*/
)
const
{
return
min_elements_per_task_
;
}
private
:
const
long
min_elements_per_task_
;
};
template
<
typename
RandomIt
,
typename
Function
,
typename
ExecutionStrategy
>
void
for_each
(
RandomIt
first
,
RandomIt
last
,
const
Function
&
function
,
ExecutionStrategy
execution_strategy
)
{
long
num_elements
=
std
::
distance
(
first
,
last
);
internal
::
for_each
(
first
,
last
,
function
,
execution_strategy
.
calculate_min_elements
(
num_elements
));
}
template
<
typename
RandomIt
,
typename
Function
>
void
for_each
(
RandomIt
first
,
RandomIt
last
,
const
Function
&
function
)
{
internal
::
for_each
(
first
,
last
,
function
);
for_each
(
first
,
last
,
function
,
dynamic_strategy
{
4
});
}
template
<
typename
Function
,
typename
ExecutionStrategy
>
void
for_each_range
(
unsigned
long
first
,
unsigned
long
last
,
const
Function
&
function
,
ExecutionStrategy
execution_strategy
)
{
auto
range
=
pls
::
internal
::
helpers
::
range
(
first
,
last
);
for_each
(
range
.
begin
(),
range
.
end
(),
function
,
execution_strategy
);
}
template
<
typename
Function
>
void
for_each_range
(
unsigned
long
first
,
unsigned
long
last
,
const
Function
&
function
)
{
auto
range
=
pls
::
internal
::
helpers
::
range
(
first
,
last
);
for_each
(
range
.
begin
(),
range
.
end
(),
function
);
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/pls/include/pls/algorithms/scan_impl.h
View file @
68af3068
...
...
@@ -69,7 +69,7 @@ class scan_task : public pls::internal::scheduling::task {
internal
::
serial_scan
(
chunk_start
,
chunk_end
,
chunk_output
,
op_
,
neutral_elem_
);
auto
last_chunk_value
=
*
(
chunk_output
+
chunk_size
-
1
);
chunk_sums_
[
i
]
=
last_chunk_value
;
});
}
,
fixed_strategy
{
1
}
);
// Calculate prefix sums of each chunks sum
// (effectively the prefix sum at the end of each chunk, then used to correct the following chunk).
...
...
@@ -85,7 +85,7 @@ class scan_task : public pls::internal::scheduling::task {
for
(;
chunk_start
!=
chunk_end
;
chunk_start
++
)
{
*
chunk_start
=
op_
(
*
chunk_start
,
chunk_sums_
[
i
-
1
]);
}
});
}
,
fixed_strategy
{
1
}
);
}
};
...
...
This diff is collapsed.
Click to expand it.
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