#include <pthread.h>
#include <iterator>
#include <vector>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include <numeric>
#include <set>
#include <list>
#include <deque>
#include <rpa/architectures/posix.h>
#include <rpa/algorithms/accumulate.h>
#include <rpa/algorithms/transform.h>
#include <rpa/containers/list.h>
#include <rpa/containers/deque.h>
#include <rpa/containers/vector.h>
#include <rpa/containers/row_buffer.h>
#include <rpa/containers/pipeline.h>
Classes | |
class | identity25< Type > |
For debugging how the algorithm 'transform' uses its variables. More... | |
struct | t25adder< Type > |
For debugging how the algorithm 'accumulate' uses its variables. More... | |
Defines | |
#define | Test(a) _Test25(#a,a) |
Typedefs | |
typedef rpa::posix_condition | cond_main_t |
Used everywhere. | |
Functions | |
static void | _Test25 (const char *aMsg, bool aBool) |
Simply checks a boolean condition and writes some informational message. | |
template<class SubThr, class Container, class PipTyp, class ObufTyp> | |
static void | tst25OneSubThrCirc (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t szOutBuf) |
template<class SubThr, class Container, class PipTyp, class ObufTyp> | |
static void | tst25OneSubThrArch (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szOutBuf) |
template<class SubThr, class Cont, class PipTyp, class ObufTyp> | |
static void | tst25ContBufOutSz (const Cont &lstDat, typename Cont::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szOutBuf) |
template<class SubThr, class Cont, class PipTyp, class ObufTyp> | |
static void | tst25ContBuf (const Cont &lstDat, typename Cont::value_type sumDat, size_t nbDbls, size_t nbThrs) |
template<class SubThr, class Cont, class ObufTyp> | |
static void | tst25Containers (size_t nbDbls, size_t nbThrs) |
This chooses the type of the underlying container of the pipeline. | |
template<class SubThr, class ObufTyp> | |
void | tst25Thr (size_t nbE, size_t nbThrs) |
template<class SubThr> | |
void | tst25ThrObuf (size_t nbE, size_t nbThrs) |
int | main (int aArgC, const char **aArgV) |
The default number of samples is chosen for a Pentium, about 1GHz.. |
#define Test | ( | a | ) | _Test25(#a,a) |
typedef rpa::posix_condition cond_main_t |
Used everywhere.
static void _Test25 | ( | const char * | aMsg, | |
bool | aBool | |||
) | [static] |
Simply checks a boolean condition and writes some informational message.
This contains all the logic for bufferizing the output of an algorithm. When an algorithm writes into a std::back_inserter, it is worth to have it write into a thread-specific buffer, which is flushed into the output iterator once a sub-thread is done with its calculation of a slice of the input range. In this example, the input ranges are taken from pipelines.
int main | ( | int | aArgC, | |
const char ** | aArgV | |||
) |
The default number of samples is chosen for a Pentium, about 1GHz..
static void tst25Containers | ( | size_t | nbDbls, | |
size_t | nbThrs | |||
) | [static] |
This chooses the type of the underlying container of the pipeline.
Each of these containers will be used for storing data in a pipeline.
static void tst25ContBuf | ( | const Cont & | lstDat, | |
typename Cont::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs | |||
) | [static] |
static void tst25ContBufOutSz | ( | const Cont & | lstDat, | |
typename Cont::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szOutBuf | |||
) | [static] |
Given the type of the input container, the pipeline underlying container, and the type of the buffer used for output, it tries various algorithms.
static void tst25OneSubThrArch | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szOutBuf | |||
) | [static] |
Only one subthread for the input algorithm. The buffer is not big enough to store all the input data, but the main thread is running at the same time and reads from it. The difference with tst25OneSubThrCirc(), is that we use a pipe_archiver.
Finite-size pipeline. There may not be enough room to store the result of the 'transform' algorithm. The underlying parameter is not 'PipTyp' because it may be a fixed-size C-style array, and it would not work for a pipe_archiver which has an infinite size.
At the beginning, the pipeline is not shut. So, reading from it hangs, if there are no data inside.
This functor will be started in a subthread.
This is the thread tree containing just one top-level sub-thread.
This is the result of the detached execution of the functor in a sub-thread.
The output elements might not be in the right order. So we sort them before comparing. This happens if there are genuine subthreads.
static void tst25OneSubThrCirc | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | szOutBuf | |||
) | [static] |
Only one subthread for the input algorithm. The buffer is not big enough to store all the input data, but the main thread is running at the same time and reads from it.
Some containers type have a maximum size.
If the underlying container has a maxsize, it will throw an exception if we put too much data in. So, we limit the pipe size.
Finite-size pipeline. There may not be enough room to store the result of the 'transform' algorithm.
This functor will be started in a subthread.
This is the thread tree containing just one top-level sub-thread.
This is the result of the detached execution of the functor in a sub-thread.
void tst25Thr | ( | size_t | nbE, | |
size_t | nbThrs | |||
) |
There are two imbricated loop on the containers type. The external container type is always limit-less. The internal one may have a limit and will therefore never used for infinite pipelines.
void tst25ThrObuf | ( | size_t | nbE, | |
size_t | nbThrs | |||
) |
This calls the other tests with several kind of output buffers for the algorithms. The role of these output buffers is to avoid that a writing algorithm actually locks an output iterator for each write. Instead. Each thread has its own output buffer.