Ускорить запуск AIX xlc io_service

Я пытаюсь скомпилировать проект, используя boost, связывая asio::io_service с boost::thread, и я получаю ошибки, которые я не знаю, как решить. Использование: IBM XL C/C++ для AIX, V11.1 (5724-X13), версия : 11.01.0000.0006 (AIX 7.1)

    "/home/clag/projects/tomas/include/boost/asio/detail/posix_fd_set_adapter.hpp", line 33.30: 1540-0198 (W) The omitted keyword "private" is assumed for base class "noncopyable".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.46: 1540-0219 (S) The call to "boost::bind" has no best match.
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1229 (I) Argument number 2 is an rvalue of type "const boost::reference_wrapper<const boost::asio::io_service>".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service>)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.58: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 50.100: 1540-1231 (I) The conversion from argument number 2 to "boost::reference_wrapper<const boost::asio::io_service>" uses "the identity conversion".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.35: 1540-0219 (S) The call to "boost::bind" has no best match.
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1229 (I) Argument number 1 is an rvalue of type "overloaded function: boost::asio::io_service::run".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1229 (I) Argument number 2 is an rvalue of type "boost::asio::io_service *".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 30.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)() const" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/bind/bind_mf_cc.hpp", line 20.5: 1540-1202 (I) No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.47: 1540-1231 (I) The conversion from argument number 1 to "unsigned long (boost::asio::io_service::*)()" uses the resolved overloaded function "size_t boost::asio::io_service::run()".
    "/home/clag/projects/tomas/ots/src/agent/agent.cc", line 52.98: 1540-1231 (I) The conversion from argument number 2 to "boost::asio::io_service *" uses "the identity conversion".
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond<CompletionCondition>".
    "/home/clag/projects/tomas/include/boost/asio/impl/write.hpp", line 276.7: 1540-0198 (W) The omitted keyword "private" is assumed for base class "detail::base_from_completion_cond>boost::asio::detail::transfer_all_t>"

Код, вызывающий ошибки:

    acceptor_thread_.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, boost::cref(*accept_io_service_))));
    for (int i = 0; i < agent_config_.threads(); i++) {
        thread_group_.create_thread(boost::bind(&boost::asio::io_service::run, work_io_service_.get()));
    }

Определения:

    boost::shared_ptr<boost::asio::io_service> accept_io_service_;
    boost::shared_ptr<boost::thread> acceptor_thread_;
    boost::shared_ptr<boost::asio::io_service> work_io_service_;
    boost::thread_group thread_group_;

Просто отметим, что это, вероятно, будет просто какой-то вариант флага, но я не могу его нигде найти, потому что один и тот же код отлично компилируется в Linux (GCC), HP-UX (aCC) и Windows (MSVC).

Спасибо за помощь


person Pinker    schedule 21.02.2013    source источник


Ответы (4)


Быстрый поиск в Google показывает, что у AIX были проблемы с разрешением перегрузки, особенно когда задействованы шаблоны. Таким образом, возможно, стоит попробовать разные подходы, чтобы уменьшить количество необходимых разрешений перегрузок.

Например, boost::mem_fn() можно использовать вместо < a href="http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html" rel="nofollow">boost::bind().

std::size_t (io_service::*run)() = &io_service::run;
boost::thread t(boost::mem_fn(run), io_service);

Кроме того, если у компилятора все еще возникают проблемы с разрешением перегрузок, рассмотрите возможность написания простого функтора. Единственное требование для boost::thread() заключается в том, что аргумент func можно копировать, а func() должно быть допустимым выражением.

struct service_runner
{
  explicit service_runner(boost::shared_ptr<boost::asio::io_service> io_service)
    : io_service(io_service)
  {}
  std::size_t operator()() { return io_service->run(); }
  boost::shared_ptr<boost::asio::io_service> io_service;
};

...

boost::thread t((service_runner(io_service)));

Другие моменты, которые следует учитывать:

person Tanner Sansbury    schedule 21.02.2013
comment
Большое спасибо за упаковку service runner, она сработала как по маслу. Первый метод с использованием boost::mem_fn() не сработал из-за The qualifier "accept_io_service_" is not defined in the current scope., что странно, потому что это переменная-член. Чтобы прокомментировать другие моменты, boost::cref() был просто тестом, который я нашел где-то на форумах, на других платформах я использую boost::shared_ptr, как и предполагалось. Еще раз спасибо за отличное предложение. - person Pinker; 22.02.2013
comment
Еще один вопрос, в AIX 6.1 (xlC_r V9.0) он не компилируется, я получаю ошибку /include/boost/thread/detail/thread.hpp", line 62.17: 1540-0204 (S) An expression of type "boost::thread *" must not be followed by the function call operator (). при использовании service_runner. Не могли бы вы объяснить мне лучше первое предложенное решение, используя mem_fn? Поскольку я действительно не понимаю std::size_t (io_service::*run)() = &io_service::run; утверждения. Спасибо - person Pinker; 04.03.2013
comment
Как вы и предположили, acceptor_thread_.reset(new boost::thread(service_runner(accept_io_service_)));, service_runner является точной копией того, что вы разместили в своем ответе. Но у меня первое решение работает ^^. Еще раз большое спасибо за вашу помощь. - person Pinker; 06.03.2013
comment
@Pinker: с помощью gcc и clang мне не удалось продублировать ошибку с помощью предоставленного кода. Для Boost 1.49 в строке 62 возникнет ошибка, если выражение func() недопустимо для предоставленного аргумента func. service_runner предоставляет operator(), поэтому он должен быть действительным. Я смог воспроизвести ошибку, только изменив предоставленный тип на boost::thread, например, предоставив boost::shared_ptr<service_runner> вместо service_runner. - person Tanner Sansbury; 06.03.2013

Просто любопытно, используете ли вы исправление библиотеки IBM boost для используемого вами компилятора? http://www-01.ibm.com/support/docview.wss?uid=swg27006911

person Catherine Morton    schedule 25.02.2013
comment
Нет, с момента его выпуска 3 года назад, используя boost 1.40.0 (это 13 выпусков назад), я ожидал, что большинство этих обходных путей уже есть в библиотеках boost, а также ожидал, что в этих 13 выпусках будет исправлено множество ошибок (хотя я использую буст 1.49.0) - person Pinker; 26.02.2013
comment
Pinker, ИМХО вы слишком оптимистичны. Я предпочитаю проверять каждую версию самостоятельно, запуская регрессионные тесты. - person vond; 10.03.2013

Глядя на сообщения для 4 возможных кандидатов, различия кажутся связанными с константами.

No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)() const, reference_wrapper<const boost::asio::io_service
>)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::reference_wrapper<const boost::asio::io_service> >(unsigned long (io_service::*)(), reference_wrapper<const boost::asio::io_service>)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)() const, io_service *)".
No candidate is better than "boost::bind<unsigned long,boost::asio::io_service,boost::asio::io_service *>(unsigned long (io_service::*)(), io_service *)".

Поскольку вы используете компилятор V11.1, есть несколько исправлений, не включенных по умолчанию, которые вы можете попробовать, используя следующие параметры.

-qxflag=EnableIssue214PartialOrdering Это включит несколько исправлений, связанных с проблемой основного языка C++ 214.

-qxflag=FunctionCVTmplArgDeduction2011 Это включает некоторые разъяснения C++ 2011 для вывода аргументов.

Эти изменения используются по умолчанию в компиляторе V12.1, но не в компиляторе V11.1.

person Catherine Morton    schedule 25.02.2013

Я добавляю дополнительный ответ, если кто-то вообще наткнется на эту проблему. Потому что я обнаружил, что это связано с тем, что компилятор не может решить, какую функцию использовать, если функции имеют одно и то же имя, но разные параметры.

Пример:

void test(int a);
void test(int a, int b);

Не будет работать и вызовет аналогичную ошибку, как указано выше.
Но изменить имя следующим образом:

void test(int a);
void test2(int a, int b);

... будет работать отлично.

Это определенно менее накладное решение, чем создание оберток (как я сам делал, пока не увидел это).

Надеюсь, кому-то это будет полезно.

person Pinker    schedule 28.07.2014