First, thank you for the reply.

On 2016-04-06 01:03, Hartmut Kaiser wrote:
>> So my questions are:
>>
>> 1. Is what I'm trying to do implementable with HPX?
>
> Yes.
>
>> 2. Am I doing something wrong in the above code?
>
> See below.
>
>> 3. What are HPX threads doing while they apparently are not doing any
>> useful work? Is it normal for them to load the CPU for no apparent reason?
>
> You told it to run on all cores, HPX is quite eager to grab all it can get.

I don't mind if HPX uses all cores it can find - when it is executing 
the work I have provided. In my case the CPU is utilized for no apparent 
reason.

>> I'm using HPX 0.9.11 with Boost 1.60 on Kubuntu 15.10 x86_64 (gcc 5.2).
>> I'm running the test app with no command line arguments and no ini files.
>
> I'm amazed you got it to work without actually blowing up, it does not work
> for me ;)
>
> First, HPX threads and std::thread don't mix well.

Well, that makes it significantly less suitable to me.

I'm exploring HPX with the intention to use it in an existing code base, 
where we have large numbers of these IO threads (which are OS kernel 
threads, naturally) that are represented with the my_thread function in 
my code sample. Sometimes, these threads are not even started by our 
code. The threads perform blocking calls like locking mutexes, waiting 
on condition variables or calling select/poll/epoll/etc. There is no 
easy way to merge these threads into a single thread that could also be 
"adopted" by HPX (either by running hpx_main in it or by some other 
means, if one exists in HPX). By "adoption" here I mean (a) the ability 
to use HPX components from that thread, like calling algorithms, using 
futures and async, and (b) the ability to execute at least some of 
iterations of the algorithms in that thread, so that the progress is 
made even when all HPX-managed kernel threads are saturated. The (b) 
part is less critical, although I presume performance will suffer if it 
is not fulfilled.

> HPX threads are
> lightweight user level threads and almost all of HPX's API functions (such
> like for_each_n) expect to run on HPX threads. If you want to run work on a
> kernel thread, you can do that by marshalling it over to one of the
> OS-thread pools HPX is managing.

Ok, so basically (a) and (b) from above are not possible? Is there a way 
to "adopt" an externally spawned thread to be used with HPX, like I 
described?

> This is turn is best done by creating an
> executor and let the for_each_n() use that to schedule work. Note, that you
> will need to use HPX from the master branch. Many of the executor facilities
> have been made available only recently.

I've tried the master branch. My original example behaves the same (i.e. 
loads CPU for no apparent reason). If I use io_pool_executor in 
my_thread I get a crash:

{stack-trace}: 15 frames:
0x7f8bea2c390d  : hpx::termination_handler(int) + 0x13d in 
/home/lastique/src/hpx/build/lib/libhpx.so.0
0x7f8be9688d10  : ??? + 0x7f8be9688d10 in 
/lib/x86_64-linux-gnu/libpthread.so.0
0x7f8bea2c26c7  : hpx::get_runtime() + 0x17 in 
/home/lastique/src/hpx/build/lib/libhpx.so.0
0x7f8bea2c3156  : hpx::get_thread_pool(char const*, char const*) + 0x56 
in /home/lastique/src/hpx/build/lib/libhpx.so.0
0x7f8bea68693a  : 
hpx::threads::executors::detail::service_executor::service_executor(char 
const*, char const*) + 0x4a in /home/lastique/src/hpx/build/lib/libhpx.so.0
0x4c0eb5        : 
hpx::threads::executors::detail::get_service_executor(hpx::threads::executors::service_executor_type,
 
char const*) + 0x79 in ./hpx-test
0x4c1167        : 
hpx::threads::executors::io_pool_executor::io_pool_executor() + 0x1b in 
./hpx-test
0x4b7b13        : my_thread() + 0x24 in ./hpx-test
0x4f6353        : void std::_Bind_simple<void 
(*())()>::_M_invoke<>(std::_Index_tuple<>) + 0x25 in ./hpx-test
0x4f587e        : std::_Bind_simple<void (*())()>::operator()() + 0x2c 
in ./hpx-test
0x4f3a3e        : std::thread::_Impl<std::_Bind_simple<void (*())()> 
 >::_M_run() + 0x1c in ./hpx-test
0x7f8be93af030  : ??? + 0x7f8be93af030 in 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
0x7f8be967f6aa  : ??? + 0x7f8be967f6aa in 
/lib/x86_64-linux-gnu/libpthread.so.0
0x7f8be8e1be9d  : clone + 0x6d in /lib/x86_64-linux-gnu/libc.so.6
{what}: Segmentation fault

With 0.9.11 I had an exception when I tried to use any executors in 
my_thread, saying that the runtime is not initialized. I guess, this 
crash indicates the same problem. Is there a way to initialize the 
runtime in my_thread?

>    #include <hpx/hpx_init.hpp>
>    #include <hpx/include/parallel_executors.hpp>
>    #include <hpx/include/parallel_for_each.hpp>
>
>    #include <iostream>
>    #include <thread>
>    #include <vector>
>    #include <iterator>
>
>    unsigned int values[1000] = {};
>
>    // this will run on one of the kernel threads from HPX's IO thread pool
>    void process(unsigned int& value)
>    {
>      // Some useful work is performed here
>      std::this_thread::sleep_for(std::chrono::microseconds(1000));
>    }
>
>    int hpx_main(int argc, char* argv[])
>    {
>      // Assume this thread is getting data
>      // from some kind of blocking IO.
>      // I want to process this data in multiple
>      // threads.
>      hpx::threads::executors::io_pool_executor exec;
>      hpx::parallel::for_each_n(
>         hpx::parallel::par.on(exec),
>         std::begin(values), 1000, &process);
>      return hpx::finalize();
>    }

For the reasons I described, it is essential for me to execute 
for_each_n in a separate std::thread.

>    int main(int argc, char *argv[])
>    {
>      std::vector< char* > args;
>      for (int i = 0; i < argc; ++i)
>        args.push_back(argv[i]);
>
>      // Use all cores for HPX threads
>      args.push_back(const_cast< char* >("--hpx:threads"));
>      args.push_back(const_cast< char* >("all"));
>      args.push_back(0);
>
>      return hpx::init(args.size()-1, args.data());
>    }
>
> Please note also, that in your case you don't need to let HPX run on all
> cores, the number of cores you specify applies to the scheduler for HPX
> threads only.

Do I understand correctly that hpx_main is executed in an OS thread from 
a pool of threads initialized by HPX, and the number of threads in that 
pool is controlled with --hpx:threads?

_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users

Reply via email to