Ускоренный протекторный код компилируется под VC ++, но не под GCC: как улучшить отладочную информацию - PullRequest
0 голосов
/ 27 июня 2018

У меня есть многопоточное (boost :: thread 1.67.0) тестовое приложение, которое прекрасно компилируется в VC ++ (MSVS2017 v15.7), но не компилируется в GCC. Брошенные ошибки действительно очень трудно понять для меня. Я думаю, что это связано с тем, как я создаю тему. Есть ли способ получить лучшую отладочную информацию?

код

#include <iostream>
#include <chrono>
using namespace std::chrono;

template<typename T>
auto toMs(T &&time) {
    return duration_cast<milliseconds>(time).count();
}

#include <string>
#include <regex>
void cxxregex(std::string const&inputString, std::string const&searchRegex)
{
    auto startTime = steady_clock::now();
    std::regex regexObj(searchRegex.data(), std::regex::extended);
    std::smatch matchObj;
    regex_search(inputString.begin(), inputString.end(), matchObj, regexObj);
    std::cout << toMs(steady_clock::now() - startTime) << "ms " << matchObj[1] << std::endl;
}

#include <boost/regex.hpp>
void boostregex(std::string const&inputString, std::string const&searchRegex)
{
    auto startTime = steady_clock::now();
    boost::regex regexObj(searchRegex.data(), boost::regex::extended);
    boost::smatch matchObj;
    regex_search(inputString.begin(), inputString.end(), matchObj, regexObj);
    std::cout << toMs(steady_clock::now() - startTime) << "ms " << matchObj[1] << std::endl;
}

#include <future>
void threadFcn(
    const int threadId,
    const std::string::const_iterator& subStringBegin,
    const std::string::const_iterator& subStringEnd,
    const boost::regex& regexObj,
    std::promise<std::pair<size_t, std::string>>& matchProm,
    const std::shared_future<std::pair<size_t, std::string>>& matchFut)
{
    boost::smatch matchObj;
    if (regex_search(subStringBegin, subStringEnd, matchObj, regexObj))
    {
        // match is found!
        if (matchFut.wait_for(0s) != std::future_status::ready) // check of not already set
            matchProm.set_value(std::make_pair(threadId, matchObj[1]));// matchObj.str()));
    }
}

#include <thread>
#include <vector>
#include <algorithm>
using namespace std::chrono_literals;
void boostparregex(std::string const &inputString, std::string const &searchRegex)
{
    auto nrOfCpus = std::thread::hardware_concurrency() / 2;
    std::cout << "(Nr of CPUs: " << nrOfCpus << ") ";

    if (searchRegex.find("^") != std::string::npos || searchRegex.find("$") != std::string::npos) {
        std::cout << "Start-of-line not supported multi-CPU. Defaulting to 1.\n";
        nrOfCpus = 1;
    }

    auto startTime = steady_clock::now();
    boost::regex regexObj(searchRegex.data(), boost::regex::extended);

    std::promise<std::pair<size_t, std::string>> foundThreadIdProm;
    auto foundThreadIdFut = foundThreadIdProm.get_future().share();
    std::vector<std::thread> threadVector; threadVector.reserve(nrOfCpus);
    auto stringSizePerThread = inputString.length() / nrOfCpus;
    for (size_t threadId = 0; threadId < nrOfCpus; threadId++) {
        // determine string start and end
        const auto begin = inputString.begin() + (threadId * stringSizePerThread);
        const auto end = inputString.end(); // all cpu's search to end of input string. they only differ in start
        // create thread
        threadVector.push_back(std::thread(threadFcn,
            (int)threadId, std::ref(begin), std::ref(end), std::ref(regexObj), std::ref(foundThreadIdProm), std::ref(foundThreadIdFut)));
    }

    if (foundThreadIdFut.wait_for(10s) == std::future_status::ready) std::cout
        << toMs(steady_clock::now() - startTime) << "ms. "
        << "Thread " << foundThreadIdFut.get().first << ": " << foundThreadIdFut.get().second << std::endl;
    else std::cerr << "Error: string not found!!" << std::endl;

    for (auto& thread : threadVector) thread.join(); // I'd rather detach... but then the references are destroyed, giving problems.
}

int main()
{
    std::string s(1000000000, 'x');
    {
        std::string s1 = "yolo" + s;
        std::cout << "yolo + ... -> cxxregex "; cxxregex(s1, "(yolo)");
        std::cout << "yolo + ... -> boostregex "; boostregex(s1, "(yolo)");
        std::cout << "yolo + ... -> boostparregex "; boostparregex(s1, "(yolo)");
    }
    {
        std::string s2 = s + "yolo";
        std::cout << "... + yolo -> cxxregex "; cxxregex(s2, "(yolo)");
        std::cout << "... + yolo -> boostregex "; boostregex(s2, "(yolo)");
        std::cout << "... + yolo -> boostparregex "; boostparregex(s2, "(yolo)");
    }
    {
        std::string s3 = "yo" + s + "lo";
        //std::cout << "... + yolo -> cxxregex "; cxxregex(s3, "(yo).*(lo)"); // doesn't even work
        std::cout << "... + yolo -> boostregex "; boostregex(s3, "(yo).*(lo)");
        std::cout << "... + yolo -> boostparregex "; boostparregex(s3, "(yo).*(lo)");
    }

    std::cin.ignore();
}

Вывод ошибки GCC

g++ main.cpp -Wall -Wextra -I../Boost/boost_1_67_0 -std=c++14

дает:

/tmp/cc9cP6LZ.o: In function `std::thread::thread<void (&)(int, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, std::promise<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::shared_future<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&), int, std::reference_wrapper<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const>, std::reference_wrapper<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const>, std::reference_wrapper<boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > >, std::reference_wrapper<std::promise<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::reference_wrapper<std::shared_future<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >(void (&)(int, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, std::promise<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::shared_future<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&), int&&, std::reference_wrapper<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const>&&, std::reference_wrapper<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const>&&, std::reference_wrapper<boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > >&&, std::reference_wrapper<std::promise<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&&, std::reference_wrapper<std::shared_future<std::pair<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&&)':
main.cpp:(.text._ZNSt6threadC2IRFviRKN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESD_RKN5boost11basic_regexIcNSE_12regex_traitsIcNSE_16cpp_regex_traitsIcEEEEEERSt7promiseISt4pairImSA_EERKSt13shared_futureISP_EEJiSt17reference_wrapperISC_ESZ_SY_ISK_ESY_ISQ_ESY_IST_EEEEOT_DpOT0_[_ZNSt6threadC5IRFviRKN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESD_RKN5boost11basic_regexIcNSE_12regex_traitsIcNSE_16cpp_regex_traitsIcEEEEEERSt7promiseISt4pairImSA_EERKSt13shared_futureISP_EEJiSt17reference_wrapperISC_ESZ_SY_ISK_ESY_ISQ_ESY_IST_EEEEOT_DpOT0_]+0x156): undefined reference to `pthread_create'
/tmp/cc9cP6LZ.o: In function `bool boost::regex_search<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)':
main.cpp:(.text._ZN5boost12regex_searchIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaINS_9sub_matchISB_EEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEbT_SJ_RNS_13match_resultsISJ_T0_EERKNS_11basic_regexIT1_T2_EENS_15regex_constants12_match_flagsESJ_[_ZN5boost12regex_searchIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaINS_9sub_matchISB_EEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEbT_SJ_RNS_13match_resultsISJ_T0_EERKNS_11basic_regexIT1_T2_EENS_15regex_constants12_match_flagsESJ_]+0xba): undefined reference to `boost::re_detail_106700::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find()'
/tmp/cc9cP6LZ.o: In function `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)':
main.cpp:(.text._ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j[_ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j]+0x2a): undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'
/tmp/cc9cP6LZ.o: In function `boost::re_detail_106700::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::perl_matcher(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)':
main.cpp:(.text._ZN5boost16re_detail_10670012perl_matcherIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaINS_9sub_matchISC_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC2ESC_SC_RNS_13match_resultsISC_SF_EERKNS_11basic_regexIcSJ_EENS_15regex_constants12_match_flagsESC_[_ZN5boost16re_detail_10670012perl_matcherIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaINS_9sub_matchISC_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC5ESC_SC_RNS_13match_resultsISC_SF_EERKNS_11basic_regexIcSJ_EENS_15regex_constants12_match_flagsESC_]+0x124): undefined reference to `boost::re_detail_106700::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)'
collect2: error: ld returned 1 exit status

1 Ответ

0 голосов
/ 27 июня 2018

Тупой, я не связывался с библиотеками boost и не включал pthread. На самом деле, я даже не скомпилировал надстройку для GCC.

Правильная команда сборки была

g++ main.cpp -Wall -Wextra -I../Boost/boost_1_67_0 -L../Boost/boost_1_67_0/stage/lib -lboost_regex -lpthread -std=c++14
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...