发出信号并保持pthread打开的有效方式
Effective way of signaling and keeping a pthread open?
我有一些代码试图运行一些密集的矩阵处理,所以我认为如果我对它进行多线程处理会更快。然而,我的意图是保持线程的活力,以便将来可以使用它进行更多的处理。问题是,多线程版本的代码运行速度比单个线程慢,我认为问题在于我发出信号/保持线程活动的方式。
我在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的函数,到目前为止,我所拥有的是一个包含1000个项目的队列(testQueue),并且有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_indexential_tests"是在获得许可的情况下从这个网站上获取的,也是所有矩阵数学发生的地方。计数器只是用于调试并确保所有实例都在运行。
它没有卡住吗?
while(true)
{
pthread_mutex_lock(&queueLock);
if(testQueue.empty())
break; //<----------------you break without unlock the mutex...
else
testQueue.pop();
pthread_mutex_unlock(&queueLock);
runtest();
}
锁定和解锁之间的部分运行速度比在单线程中慢。
互斥对象正在减慢您的速度。你应该只锁定关键部分,如果你想加快速度,尽量不要使用互斥。
您可以通过函数参数提供测试,而不是使用队列。
避免使用互斥的一种方法是使用不删除的vector
和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();
}
相关文章:
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 只需要知道我在c ++中打印模式的方式是否有效,或者有另一种方法可以有效地做到这一点
- 如何以更有效的方式检查一个数字是否是素数?
- 为什么以这种方式使用迭代器有效?
- EIGEN地图类:将C阵列映射到VectorXD指针以有效的方式
- 以有效的方式从 Node .js运行 C 或C++代码
- 在这种情况下,如何以有效的方式使用模板
- 可能以有效的方式在模拟的循环中进行多线程
- 更有效的填充unordered_set方式?
- 持有多个特征矩阵Xd的最有效方式
- 存储资源的最有效方式
- 存储IPv4/IPv6地址的有效方式
- 使用单个索引访问子矩阵的有效方式
- 发出信号并保持pthread打开的有效方式
- 顺时针和逆时针旋转阵列的有效方式
- 使用Qt和OpenCV读取和处理视频文件的有效方式
- 这是将字符串作为参数传递给函数的内存有效方式
- 这是在c++中运行循环的有效方式吗?
- 在内存映射文件中交换字节的有效方式
- 将跨步数据复制到CUDA设备和从CUDA设备复制跨步数据的有效方式