C++ pthread程序需要更长时间吗
也许我把自己和线程搞混了,但是我对线程的理解相互冲突 我创建了一个使用POSIXC++ pthread程序需要更长时间吗,c++,multithreading,pthreads,C++,Multithreading,Pthreads,也许我把自己和线程搞混了,但是我对线程的理解相互冲突 我创建了一个使用POSIXpthreads的程序。如果不使用这些线程,程序运行需要0.061723秒,而使用线程则需要0.081061秒 起初我认为这是应该发生的,因为线程允许某些事情发生,而其他事情应该能够发生。i、 e.在一个线程上处理大量数据,而在另一个线程上仍有响应UI,这意味着CPU在处理UI和处理数据之间分配时间时,数据处理将花费更长的时间 然而,多线程的目的当然是让程序利用多个CPU/内核 你可以看出我是一个中间人,所以如果这是
pthread
s的程序。如果不使用这些线程,程序运行需要0.061723秒,而使用线程则需要0.081061秒
起初我认为这是应该发生的,因为线程允许某些事情发生,而其他事情应该能够发生。i、 e.在一个线程上处理大量数据,而在另一个线程上仍有响应UI,这意味着CPU在处理UI和处理数据之间分配时间时,数据处理将花费更长的时间
然而,多线程的目的当然是让程序利用多个CPU/内核
你可以看出我是一个中间人,所以如果这是一个简单的问题,请原谅
但是我应该期待这个项目做什么呢
我在2012年年中的Macbook Pro 13“基本机型上运行此功能。CPU是22纳米“常春藤桥”2.5 GHz Intel“Core i5”处理器(3210M),在一个硅芯片上有两个独立的处理器“核心”
用代码更新
这是主要功能。为了方便起见,我没有添加变量声明,但我相信您可以通过名称了解每个变量的作用:
// Loop through all items we need to process
//
while (totalNumberOfItemsToProcess > 0 && numberOfItemsToProcessOnEachIteration > 0 && startingIndex <= totalNumberOfItemsToProcess)
{
// As long as we have items to process...
//
// Align the index with number of items to process per iteration
//
const uint endIndex = startingIndex + (numberOfItemsToProcessOnEachIteration - 1);
// Create range
//
Range range = RangeMake(startingIndex,
endIndex);
rangesProcessed[i] = range;
// Create thread
//
// Create a thread identifier, 'newThread'
//
pthread_t newThread;
// Create thread with range
//
int threadStatus = pthread_create(&newThread, NULL, processCoordinatesInRangePointer, &rangesProcessed[i]);
if (threadStatus != 0)
{
std::cout << "Failed to create thread" << std::endl;
exit(1);
}
// Add thread to threads
//
threadIDs.push_back(newThread);
// Setup next iteration
//
// Starting index
//
// Realign the index with number of items to process per iteration
//
startingIndex = (endIndex + 1);
// Number of items to process on each iteration
//
if (startingIndex > (totalNumberOfItemsToProcess - numberOfItemsToProcessOnEachIteration))
{
// If the total number of items to process is less than the number of items to process on each iteration
//
numberOfItemsToProcessOnEachIteration = totalNumberOfItemsToProcess - startingIndex;
}
// Increment index
//
i++;
}
std::cout << "Number of threads: " << threadIDs.size() << std::endl;
// Loop through all threads, rejoining them back up
//
for ( size_t i = 0;
i < threadIDs.size();
i++ )
{
// Wait for each thread to finish before returning
//
pthread_t currentThreadID = threadIDs[i];
int joinStatus = pthread_join(currentThreadID, NULL);
if (joinStatus != 0)
{
std::cout << "Thread join failed" << std::endl;
exit(1);
}
}
//循环浏览我们需要处理的所有项目
//
虽然(totalNumberOfItemsToProcess>0&&NumberOfItemsToProcessOneAchitation>0&&startingIndex如果我错了,请纠正我,但是,我认为问题在于如何测量经过的时间。我已移动到gettimeofday()
报告的时间更短,从非线程时间22.629000 ms
到线程时间8.599000 ms
人们觉得这对吗
当然,我最初的问题是基于一个多线程程序是否应该更快,因此出于这个原因,我不会将这个答案标记为正确的答案。您是以何种方式使用线程来加速程序的?细节很重要。生成线程有开销。我有十个线程,每个线程从一个坐标数组。然后对这些值执行计算。例如,thread0获取索引0-29999。thread1获取索引30000-59999等。首先,最重要的是,由于数据同步迫使所有参与者暂停,因此并发性对您的执行造成了沉重的成本。并发性只有在您能够独立完成足够的工作时才有用同时,运行时的改进远远超过了同步成本。这绝对不容易。在线程方面,代码非常重要。据我们所知,您正在同步链接线程(您会惊讶于人们在启动线程的循环中频繁填充thrds[i]。join();
)。发布您的代码(至少是线程体系结构和数据分区)。@AdamCarter在编写时,不要麻烦启动超过std::thread::hardware\u concurrency()
线程,除非您的程序是IO绑定的(听起来并不是这样,因此,任何超过这一点的事情都可能会引入比您需要的更多的硬件争用)。如果您在单核系统上执行多线程程序,它可能会比在单线程程序上执行相同任务的速度慢。我的计算机规格(在我的问题中)如果说一个芯片上有两个核,那么多线程的不是应该更快吗?从22.629000毫秒加速到8.599000毫秒更快,不是吗?显然,工作量还是一样的,所以CPU时间没有减少。因为创建和同步线程有一些开销,CPU时间甚至略有增加。好吧,那么最好的方法是在我的场景中,测量所用的时间,是墙时间吗?对吗?如果有可能找出,平均有多少个处理器用于并行处理,你可以用时钟除以平均使用的线程数,但我不知道如何测量。也许可以用像Valgrind
void processCoordinatesAtIndex(uint index)
{
const int previousIndex = (index - 1);
// Get coordinates from terrain
//
Coordinate3D previousCoordinate = terrain[previousIndex];
Coordinate3D currentCoordinate = terrain[index];
// Calculate...
//
// Euclidean distance
//
double euclideanDistance = Coordinate3DEuclideanDistanceBetweenPoints(previousCoordinate, currentCoordinate);
euclideanDistances[index] = euclideanDistance;
// Angle of slope
//
double slopeAngle = Coordinate3DAngleOfSlopeBetweenPoints(previousCoordinate, currentCoordinate, false);
slopeAngles[index] = slopeAngle;
}
void processCoordinatesInRange(Range range)
{
for ( uint i = range.min;
i <= range.max;
i++ )
{
processCoordinatesAtIndex(i);
}
}
void *processCoordinatesInRangePointer(void *threadID)
{
// Cast the pointer to the right type
//
struct Range *range = (struct Range *)threadID;
processCoordinatesInRange(*range);
return NULL;
}
std::vector<Coordinate3D> terrain;
std::vector<double> euclideanDistances;
std::vector<double> slopeAngles;
std::vector<Range> rangesProcessed;
std::vector<pthread_t> threadIDs;