C ++并发队列:使用>较慢1个主题

时间:2017-03-10 03:23:34

标签: c++ multithreading performance queue fifo

队列与两个不同的锁同时发生:一个用于enqueue()以保护同时排队的多个线程&一个用于dequeue()获得相同的效果。

如果队列已满,则添加(入队)只是跳过(返回)插入。 如果队列为空,则Remove(dequeue)会跳过删除。

我使用doRandom()生成0到1之间的一堆随机数。我使用这些数字来决定是否添加/删除。

性能:我尝试使用静态/动态线程分配来测试队列。对于两种分配算法,> 1个线程的执行时间明显较慢。

   //g++ -std=c++0x -pthread -o block blocking.cpp;./block

    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <atomic>
    #include <random>
    #include <stdio.h>  
    #include <time.h>
    #include <stdlib.h>
    #include <ctime>
    #include <condition_variable>
    using namespace std;

    #define NUMBER_OF_THREADS 1
    #define NUMBER_OF_OPERATIONS 10000000
    #define QUEUE_CAPACITY 1000000

    std::vector<double> getRandom();


    template <class T> class BoundedQueue {

        private:
            T * array;  
            int head, tail, capacity;
            std::mutex enqLock, deqLock;
            std::atomic<long> sharedCounter;
            std::condition_variable notEmptyCondition, notFullCondition;    

        public:
            void staticAllocation(double randomNumbers[], int threadID);
            void dynamicAllocation(double randomNumbers[]);
            void add (T x);
            BoundedQueue ();
            void remove ();
    };

    template <class T> BoundedQueue<T>::BoundedQueue () {
        capacity = QUEUE_CAPACITY;
        array = new T[capacity];
        head = 0;
        tail = 0;
        sharedCounter = 0;
    }

    template <class T> void BoundedQueue<T>::add (T x) {

            enqLock.lock();

            if (tail - head == capacity) {
                enqLock.unlock();
                return;
            }
            array[tail % capacity] = x;
            tail++;

            enqLock.unlock();
    }   

    template <class T> void BoundedQueue<T>::remove() {

            deqLock.lock();
            if (tail - head == 0) {
                deqLock.unlock();
                return;
            }
            T result = array [head % capacity];
            head++;

            deqLock.unlock();
    }   

    template <class T> void BoundedQueue<T>::dynamicAllocation(double randomNumbers[]) {

        long i = 0;
        while (i < QUEUE_CAPACITY) {
            i = sharedCounter.fetch_add(1, std::memory_order_relaxed);
            if(randomNumbers[i] <= 0.5) add(0);
            else remove();
        }   
    }

    template <class T> void BoundedQueue<T>::staticAllocation (double randomNumbers[], int threadID) {

        int split = NUMBER_OF_OPERATIONS / NUMBER_OF_THREADS;   
        for (int i = threadID * split; i < (threadID * split) + split; i++) {
            if(randomNumbers[i] <= 0.5) add(0);
            else remove();
        }
    }

    std::vector<double> getRandom() {

        std::vector<double> numbers;
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_real_distribution<> dis(0,1);

        for(int i = 0; i < NUMBER_OF_OPERATIONS; i++) numbers.push_back(dis(gen));

        return numbers;
    }   

    int main () {

        BoundedQueue<int> bQ;
        std::vector<double> temp = getRandom();
        double* randomNumbers = &temp[0];

        std::thread myThreads[NUMBER_OF_THREADS];

        clock_t begin = clock();

        for(int i = 0; i < NUMBER_OF_THREADS; i++) {
                    myThreads[i] = std::thread ( [&] {bQ.dynamicAllocation(randomNumbers); });
        }

        for(int i = 0; i < NUMBER_OF_THREADS; i++) {
            if(myThreads[i].joinable()) myThreads[i].join();
        }   

        clock_t end = clock();

        cout << double(end-begin) * 1000 / CLOCKS_PER_SEC;
        return 0;
    }

1 个答案:

答案 0 :(得分:0)

这里没有并行性。请注意,所有线程几乎都会被序列化,因为您在函数的开头锁定并在结束时释放它。

虽然由于缺乏并行性而在线程之间划分工作,但锁定/解锁的开销占主导地位,并且整体显示与单线程相比较大的执行时间。

所以并发性但是没有并行性,我们只需支付同步价格而没有性能优势。