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
e0604d1f
authored
Feb 18, 2020
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add unbalanced tree search benchmark for v3.
parent
d5b66aba
Pipeline
#1408
failed with stages
in 37 seconds
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
44 additions
and
164 deletions
+44
-164
app/benchmark_unbalanced/CMakeLists.txt
+3
-3
app/benchmark_unbalanced/function_node.cpp
+0
-28
app/benchmark_unbalanced/main.cpp
+41
-60
app/benchmark_unbalanced/node.h
+0
-73
No files found.
app/benchmark_unbalanced/CMakeLists.txt
View file @
e0604d1f
add_executable
(
benchmark_unbalanced
main.cpp node.h function_node.cpp picosha2.h
)
target_link_libraries
(
benchmark_unbalanced pls
)
add_executable
(
benchmark_unbalanced
_pls_v3 main.cpp
)
target_link_libraries
(
benchmark_unbalanced
_pls_v3 benchmark_runner benchmark_base
pls
)
if
(
EASY_PROFILER
)
target_link_libraries
(
benchmark_unbalanced easy_profiler
)
target_link_libraries
(
benchmark_unbalanced
_pls_v3
easy_profiler
)
endif
()
app/benchmark_unbalanced/function_node.cpp
deleted
100644 → 0
View file @
d5b66aba
#include "node.h"
namespace
uts
{
node_state
node
::
generate_child_state
(
uint32_t
index
)
{
node_state
result
;
picosha2
::
hash256_one_by_one
hasher
;
hasher
.
process
(
state_
.
begin
(),
state_
.
end
());
auto
index_begin
=
reinterpret_cast
<
uint8_t
*>
(
&
index
);
hasher
.
process
(
index_begin
,
index_begin
+
4
);
hasher
.
finish
();
hasher
.
get_hash_bytes
(
result
.
begin
(),
result
.
end
());
return
result
;
}
double
node
::
get_state_random
()
{
int32_t
state_random_integer
;
uint32_t
b
=
((
uint32_t
)
state_
[
16
]
<<
24
)
|
((
uint32_t
)
state_
[
17
]
<<
16
)
|
((
uint32_t
)
state_
[
18
]
<<
8
)
|
((
uint32_t
)
state_
[
19
]
<<
0
);
b
=
b
&
0x7fffffff
;
// Mask out negative values
state_random_integer
=
static_cast
<
int32_t
>
(
b
);
return
(
double
)
state_random_integer
/
(
double
)
INT32_MAX
;
}
}
app/benchmark_unbalanced/main.cpp
View file @
e0604d1f
#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/parallel_result.h"
#include "pls/internal/scheduling/scheduler_memory.h"
using
namespace
pls
::
internal
::
scheduling
;
#include "pls/internal/scheduling/static_scheduler_memory.h"
#include "node.h"
using
namespace
pls
::
internal
::
scheduling
;
const
int
SEED
=
42
;
const
int
ROOT_CHILDREN
=
140
;
const
double
Q
=
0.124875
;
const
int
NORMAL_CHILDREN
=
8
;
#include "benchmark_runner.h"
#include "benchmark_base/unbalanced.h"
const
int
NUM_NODES
=
71069
;
using
namespace
comparison_benchmarks
::
base
;
parallel_result
<
int
>
count_child_nodes
(
uts
::
node
&
node
)
{
int
child_count
=
1
;
std
::
vector
<
uts
::
node
>
children
=
node
.
spawn_child_nodes
();
#include <atomic>
if
(
children
.
empty
())
{
return
child_count
;
int
count_child_nodes
(
unbalanced
::
node
&
node
)
{
if
(
node
.
get_num_children
()
<
1
)
{
return
1
;
}
std
::
vector
<
int
>
results
(
children
.
size
());
for
(
size_t
i
=
0
;
i
<
children
.
size
();
i
++
)
{
size_t
index
=
i
;
auto
lambda
=
[
&
,
index
]
{
results
[
index
]
=
count_child_nodes
(
children
[
index
]);
};
using
child_type
=
pls
::
lambda_task_by_value
<
typeof
(
lambda
)
>
;
pls
::
scheduler
::
spawn_child
<
child_type
>
(
lambda
);
}
pls
::
scheduler
::
wait_for_all
();
for
(
auto
result
:
results
)
{
child_count
+=
result
;
std
::
atomic
<
int
>
count
{
1
};
for
(
int
i
=
0
;
i
<
node
.
get_num_children
();
i
++
)
{
scheduler
::
spawn
([
i
,
&
count
,
&
node
]
{
unbalanced
::
node
child_node
=
node
.
spawn_child_node
(
i
);
count
.
fetch_add
(
count_child_nodes
(
child_node
));
});
}
scheduler
::
sync
();
return
c
hild_c
ount
;
return
count
;
}
parallel_result
<
int
>
unbalanced_tree_search
(
int
seed
,
int
root_children
,
double
q
,
int
normal_children
)
{
int
result
;
auto
lambda
=
[
&
]
{
uts
::
node
root
(
seed
,
root_children
,
q
,
normal_children
);
result
=
count_child_nodes
(
root
);
};
using
child_type
=
pls
::
lambda_task_by_reference
<
typeof
(
lambda
)
>
;
pls
::
scheduler
::
spawn_child
<
child_type
>
(
lambda
);
pls
::
scheduler
::
wait_for_all
();
return
result
;
int
unbalanced_tree_search
(
int
seed
,
int
root_children
,
double
q
,
int
normal_children
)
{
unbalanced
::
node
root
(
seed
,
root_children
,
q
,
normal_children
);
return
count_child_nodes
(
root
);
}
constexpr
size_t
MAX_NUM_THREADS
=
5
;
constexpr
int
MAX_NUM_THREADS
=
8
;
constexpr
int
MAX_NUM_TASKS
=
256
;
constexpr
int
MAX_STACK_SIZE
=
1024
*
2
;
constexpr
size_t
MAX_NUM_TASKS
=
128
;
static_scheduler_memory
<
MAX_NUM_THREADS
,
MAX_NUM_TASKS
,
MAX_STACK_SIZE
>
global_scheduler_memory
;
constexpr
size_t
MAX_NUM_CONTS
=
128
;
constexpr
size_t
MAX_CONT_SIZE
=
512
;
int
main
(
int
argc
,
char
**
argv
)
{
int
num_threads
;
string
directory
;
benchmark_runner
::
read_args
(
argc
,
argv
,
num_threads
,
directory
);
volatile
int
result
;
int
main
()
{
PROFILE_ENABLE
static_scheduler_memory
<
MAX_NUM_THREADS
,
MAX_NUM_TASKS
,
MAX_NUM_CONTS
,
MAX_CONT_SIZE
>
static_scheduler_memory
;
string
test_name
=
to_string
(
num_threads
)
+
".csv"
;
string
full_directory
=
directory
+
"/PLS_v3/"
;
benchmark_runner
runner
{
full_directory
,
test_name
};
scheduler
scheduler
{
static_scheduler_memory
,
MAX_NUM_THREADS
};
scheduler
scheduler
{
global_scheduler_memory
,
(
unsigned
)
num_threads
};
runner
.
run_iterations
(
unbalanced
::
NUM_ITERATIONS
,
[
&
]()
{
scheduler
.
perform_work
([
&
]()
{
return
scheduler
::
par
([
&
]()
{
return
unbalanced_tree_search
(
SEED
,
ROOT_CHILDREN
,
Q
,
NORMAL_CHILDREN
);
},
[]()
{
return
parallel_result
<
int
>
{
0
};
}).
then
([](
int
a
,
int
)
{
result
=
a
;
return
parallel_result
<
int
>
{
0
};
});
unbalanced_tree_search
(
unbalanced
::
SEED
,
unbalanced
::
ROOT_CHILDREN
,
unbalanced
::
Q
,
unbalanced
::
NORMAL_CHILDREN
);
});
},
unbalanced
::
WARMUP_ITERATIONS
);
runner
.
commit_results
(
true
);
PROFILE_SAVE
(
"test_profile.prof"
)
}
//int main() {
...
...
app/benchmark_unbalanced/node.h
deleted
100644 → 0
View file @
d5b66aba
#ifndef UTS_NODE_H
#define UTS_NODE_H
#include <cstdint>
#include <array>
#include <vector>
#include "picosha2.h"
namespace
uts
{
using
node_state
=
std
::
array
<
uint8_t
,
20
>
;
/**
* Node of an unballanced binomial tree (https://www.cs.unc.edu/~olivier/LCPC06.pdf).
* To build up the tree recursivly call spawn_child_nodes on each node until leaves are reached.
* The tree is not built up directly in memory, but rather by the recursive calls.
*/
class
node
{
// The state is used to allow a deterministic tree construction using sha256 hashes.
node_state
state_
;
// Set this to a positive number for the root node to start the tree with a specific size
int
root_children_
;
// general branching factors
double
q_
;
int
b_
;
// Private constructor for children
node
(
node_state
state
,
double
q
,
int
b
)
:
state_
{
state
},
root_children_
{
-
1
},
q_
{
q
},
b_
{
b
}
{}
std
::
array
<
uint8_t
,
20
>
generate_child_state
(
uint32_t
index
);
double
get_state_random
();
public
:
node
(
int
seed
,
int
root_children
,
double
q
,
int
b
)
:
state_
({{}}),
root_children_
{
root_children
},
q_
{
q
},
b_
{
b
}
{
for
(
int
i
=
0
;
i
<
16
;
i
++
)
{
state_
[
i
]
=
0
;
}
state_
[
16
]
=
static_cast
<
uint8_t
>
(
0xFF
&
(
seed
>>
24
));
state_
[
17
]
=
static_cast
<
uint8_t
>
(
0xFF
&
(
seed
>>
16
));
state_
[
18
]
=
static_cast
<
uint8_t
>
(
0xFF
&
(
seed
>>
8
));
state_
[
19
]
=
static_cast
<
uint8_t
>
(
0xFF
&
(
seed
>>
0
));
picosha2
::
hash256_one_by_one
hasher
;
hasher
.
process
(
state_
.
begin
(),
state_
.
end
());
hasher
.
finish
();
hasher
.
get_hash_bytes
(
state_
.
begin
(),
state_
.
end
());
}
std
::
vector
<
node
>
spawn_child_nodes
()
{
double
state_random
=
get_state_random
();
int
num_children
;
if
(
root_children_
>
0
)
{
num_children
=
root_children_
;
// Root always spawns children
}
else
if
(
state_random
<
q_
)
{
num_children
=
b_
;
}
else
{
num_children
=
0
;
}
std
::
vector
<
node
>
result
;
for
(
int
i
=
0
;
i
<
num_children
;
i
++
)
{
result
.
push_back
(
node
(
generate_child_state
(
i
),
q_
,
b_
));
}
return
result
;
}
};
}
#endif //UTS_NODE_H
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