0

我有一些代码试图运行一些密集的矩阵处理,所以我认为如果我多线程它会更快。但是,我的目的是让线程保持活动状态,以便将来可以使用它进行更多处理。这是问题所在,代码的多线程版本比单线程运行得慢,我相信问题在于我发出信号/保持线程存活的方式。

我在 Windows 和 C++ 上使用 pthreads。这是我的线程代码,其中runtest()是发生矩阵计算的函数:

void* playQueue(void* arg)
{
    while(true)
    {
        pthread_mutex_lock(&queueLock);
        if(testQueue.empty())
            break;
        else
            testQueue.pop();
        pthread_mutex_unlock(&queueLock);
        runtest();
    }
    pthread_exit(NULL); 
}

playQueue()函数是传递给 pthread的函数,到目前为止,我所拥有的是一个队列(testQueue),可以说是 1000 个项目,并且有 100 个线程。每个线程将继续运行,直到队列为空(因此互斥锁内的东西)。

我相信多线程运行如此缓慢的原因是因为所谓的虚假共享(我认为?)以及我向线程发出信号以调用runtest()并保持线程存活的方法很差。

什么是这样做的有效方法,以便多线程版本将运行得更快(或至少与迭代版本一样快)?

这是我的代码的完整版本(减去矩阵的东西)

# include <cstdlib>
# include <iostream>
# include <cmath>
# include <complex>
# include <string>
# include <pthread.h>
# include <queue>

using namespace std;

# include "matrix_exponential.hpp"
# include "test_matrix_exponential.hpp"
# include "c8lib.hpp"
# include "r8lib.hpp"

# define NUM_THREADS 3

int main ( );
int counter;
queue<int> testQueue;
queue<int> anotherQueue;
void *playQueue(void* arg);
void runtest();
void matrix_exponential_test01 ( );
void matrix_exponential_test02 ( );
pthread_mutex_t anotherLock;
pthread_mutex_t queueLock;
pthread_cond_t queue_cv;

int main ()

{
    counter = 0;

   /* for (int i=0;i<1; i++)
        for(int j=0; j<1000; j++)
        {
            runtest();
          cout << counter << endl;
        }*/

    pthread_t threads[NUM_THREADS];
    pthread_mutex_init(&queueLock, NULL);
    pthread_mutex_init(&anotherLock, NULL);
    pthread_cond_init (&queue_cv, NULL);
    for(int z=0; z<1000; z++)
    {
        testQueue.push(1);
    }
    for( int i=0; i < NUM_THREADS; i++ )
    {
       pthread_create(&threads[i], NULL, playQueue, (void*)NULL);
    }
    while(anotherQueue.size()<NUM_THREADS)
    {

    }
    cout << counter;
    pthread_mutex_destroy(&queueLock);
    pthread_cond_destroy(&queue_cv);
    pthread_cancel(NULL);
    cout << counter;
    return 0;
}

void* playQueue(void* arg)
{
    while(true)
    {
        cout<<counter<<endl;
        pthread_mutex_lock(&queueLock);
        if(testQueue.empty()){
                pthread_mutex_unlock(&queueLock);
            break;
        }
        else
            testQueue.pop();
        pthread_mutex_unlock(&queueLock);
        runtest();
    }
    pthread_mutex_lock(&anotherLock);
    anotherQueue.push(1);
    pthread_mutex_unlock(&anotherLock);
    pthread_exit(NULL);
}

void runtest()
{
      counter++;
      matrix_exponential_test01 ( );
      matrix_exponential_test02 ( );
}

所以在这里,“matrix_exponential_tests”是从这个网站上获得许可的,是所有矩阵数学发生的地方。该计数器仅用于调试并确保所有实例都在运行。

4

1 回答 1

3

不卡住吗?

while(true)
{
    pthread_mutex_lock(&queueLock);
    if(testQueue.empty())
        break; //<----------------you break without unlock the mutex...
    else
        testQueue.pop();
    pthread_mutex_unlock(&queueLock);
    runtest();
}

锁定和解锁之间的部分比在单线程中运行得慢。

互斥体正在减慢您的速度。你应该只锁定关键部分,如果你想加快速度,尽量不要使用互斥锁。

您可以通过函数参数提供测试而不是使用队列来做到这一点。

避免使用互斥锁的一种方法是使用 avector而不删除和std::atomic_int(c++11) 作为索引(或锁定仅获取当前索引和增量)

或像这样使用迭代器:

vector<test> testVector;
vector<test>::iterator it;
//when it initialized to:
it = testVector.begin();

现在你的循环可以是这样的:

while(true)
{
    vector<test>::iterator it1;
    pthread_mutex_lock(&queueLock);
    it1 = (it==testVector.end())? it : it++; 
    pthread_mutex_unlock(&queueLock);

    //now you outside the critical section: 
    if(it==testVector.end())
        break; 
    //you don't delete or change the vector
    //so you can use the it1 iterator freely
    runtest();
}
于 2014-09-10T19:02:39.080 回答