多线程对性能没有影响

时间:2016-10-24 06:36:59

标签: c++ multithreading performance parallel-processing packet-sniffers

我正在处理我的数据包嗅探器。有一个workerConnection()函数,它对数据包执行如下的主进程。 它从_Connection_buffer读取一个定义为std::string* _Connection_buffer= new std::string[_Max_Element_Connection_buffer]的数据包,然后按空白分隔数据包并对它们执行一些操作。 除了执行workerConnection()的并行处理之外,everythings运行良好。

正如在workerConnection()中可以看到的那样,在第一个循环中,每个线程都使用一个唯一的数字作为它自己的“MyID'”。然后使用其MyID作为从_Connection_buffer读取数据包的偏移量。

我确信通过并行处理workerConnection(),每个线程都不处理所有数据包,只处理(_Max_Element_Connection_buffer / _ConnectionThreadCount)数据包。

void
workerConnection() {
    short MyID = 0;
    _Connection_tn->_mtx.lock();

    for (int n = 0; n < _ConnectionThreadCount; n++) {
        if (_Connection_tn->getMyNumber[n] != 100) {
            MyID = _Connection_tn->getMyNumber[n];
            _Connection_tn->getMyNumber[n] = 100;
            break;
        }
    }
    _Connection_tn->_mtx.unlock();
    LOG_INFO("Session Worker :%d started", MyID);
    long int index = 0;
    s_EntryItem* entryItem = NULL; 
    uint32_t srcIP_num;
    uint64_t p_counter=0;

    std::string connectionPayload1 = "";         connectionPayload1.reserve(40);
    std::string connectionPayload2 = "";         connectionPayload2.reserve(40);
    std::string connectionPayload = "";         connectionPayload.reserve(150);

    std::string part;         part.reserve(30);
    std::string srcIP_str;    srcIP_str.reserve(15);
    std::string t;            t.reserve(50);
    std::string line;         line.reserve(_snapLengthConnection + 1);
    std::string Protocol;     Protocol.reserve(3);
    std::string srcIP_port;   Protocol.reserve(7);

    std::vector<std::string> _CStorage(_storage_Count_Connection);
    struct timeval start, end;
    long mtime, secs, usecs;        
    gettimeofday(&start, NULL);
    for (index = MyID; index < _Max_Element_Connection_buffer; index+=_ConnectionThreadCount) {                        
        if (unlikely(p_counter++ >= (_Connection_flag->_Number - MyID)) ) { 
            LOG_INFO("sleeped");
            boost::this_thread::sleep(boost::posix_time::milliseconds(20));
            continue;
        }
        line = _Connection_buffer[index];
        if(line.size()<_storage_Count_Connection)
            continue;
        part = line.substr(_column_ConnectionConditionLocation, ConnectionCondition.length() + 5);
        if (part.find("My Packet") == std::string::npos) {      //assume always false.
            LOG_INFO("Part: %s, Condition: %s", part.c_str(), ConnectionCondition.c_str());
            continue;
        }                                    
        boost::split(_CStorage,line,boost::is_any_of(" "));
        t = _CStorage[_column_ConnectionUserIP];   
        auto endSource = t.find("/", 0);
        srcIP_str = t.substr(0, endSource);
        try {
            srcIP_num = boost::asio::ip::address_v4::from_string(srcIP_str).to_ulong();
        } catch (...) {
            continue;
        }
        entryItem = searchIPTable(srcIP_num);
        if (entryItem == NULL) {
            continue;
        }
        int ok = processConnection(srcIP_num, connectionPayload1, connectionPayload2, &_CStorage);
        if (!ok) {
            continue;
        }
        auto startSource = t.find("/", 8) + 1;
        endSource = t.find("-", startSource);            
        connectionPayload2+=t.substr(startSource, endSource - startSource);

        connectionPayload2+=_CStorage[_column_ConnectionProtocol];

        entryItem->_mtx.lock();
        if (entryItem->InUse != false) {
            connectionPayload = entryItem->payload1;
            connectionPayload += connectionPayload1;
            connectionPayload += entryItem->payload2;
            connectionPayload += connectionPayload2;
        }
        entryItem->_mtx.unlock();
    }
    gettimeofday(&end, NULL);
    secs  = end.tv_sec  - start.tv_sec;
    usecs = end.tv_usec - start.tv_usec;
    mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;
    LOG_INFO("Worker %d :Elapsed time for %lu times running Connection Worker is %ld millisecs\n",MyID,index, mtime);  

    LOG_INFO("Connection Worker %d :stopped",MyID);
}

所以现在,有一个问题让我发疯。使用一个或两个或n个线程处理所有数据包需要相等的时间。 如前所述,在多线程上,我确信每个线程只处理_Max_Element_Connection_buffer / _ConnectionThreadCount包。

我在虚拟的ubuntu 14.04上运行我的程序,它有20G RAM和4个CPU。主机操作系统Windows 8并有8个CPU。 我的一个虚拟ubuntu处理器的规格如下所示:

  

处理器:3

     

vendor_id:GenuineIntel

     

cpu family:6

     

型号:60

     

型号名称:Intel(R)Core(TM)i5-4460 CPU @ 3.20GHz

     

踩:3

     

cpu MHz:3192.718

     

缓存大小:6144 KB

     

物理ID:0

     兄弟姐妹:4

     

核心ID:3

     

cpu cores:4

使用1,2,4和8个线程处理我的程序的结果如下:

_Connection_buffer元素的数量= 10,000

使用一个帖子:

Worker 0 :Elapsed time for 10000 times running Connection Worker is 149 millisecs

使用2个线程:

Worker 0 :Elapsed time for 10000 times running Connection Worker is 122 millisecs
Worker 1 :Elapsed time for 10001 times running Connection Worker is 127 millisecs

using 4 threads:
Worker 0 :Elapsed time for 10000 times running Connection Worker is 127 millisecs
Worker 1 :Elapsed time for 10002 times running Connection Worker is 129 millisecs
Worker 2 :Elapsed time for 10001 times running Connection Worker is 138 millisecs
Worker 3 :Elapsed time for 10003 times running Connection Worker is 140 millisecs

使用8个线程。

Worker 0 :Elapsed time for 10007 times running Connection Worker is 135 millisecs
Worker 1 :Elapsed time for 10000 times running Connection Worker is 154 millisecs
Worker 2 :Elapsed time for 10002 times running Connection Worker is 153 millisecs
Worker 3 :Elapsed time for 10003 times running Connection Worker is 158 millisecs
Worker 4 :Elapsed time for 10006 times running Connection Worker is 169 millisecs
Worker 5 :Elapsed time for 10004 times running Connection Worker is 170 millisecs
Worker 6 :Elapsed time for 10005 times running Connection Worker is 176 millisecs
Worker 7 :Elapsed time for 10001 times running Connection Worker is 178 millisecs

0 个答案:

没有答案