串行代码比C中只使用一个线程慢得多?
因此,我用线程进行了一些基准测试,并编写了以下代码: resp_threadless[]和resp_threaded[]是全局int数组,其大小为n串行代码比C中只使用一个线程慢得多?,c,multithreading,parallel-processing,C,Multithreading,Parallel Processing,因此,我用线程进行了一些基准测试,并编写了以下代码: resp_threadless[]和resp_threaded[]是全局int数组,其大小为n int n = 100000; void function() { for (long j = 0; j < n; ++j) { int count = 0; double x = vetor[j]; while (x > 1.0) { x = sqrt(x); ++count;
int n = 100000;
void function() {
for (long j = 0; j < n; ++j) {
int count = 0;
double x = vetor[j];
while (x > 1.0) {
x = sqrt(x);
++count;
}
resp_threadless[j] = count;
}
}
DWORD WINAPI function_th( LPVOID lpParam ) {
for (long j = 0; j < n; ++j) {
int count = 0;
double x = vetor[j];
while (x > 1.0) {
x = sqrt(x);
++count;
}
resp_threadless[j] = count;
}
}
第二个是这样的:
HANDLE hThreadArray[1];
DWORD dwThreads[1];
hThreadArray[0] = CreateThread(NULL, 0, function_th, NULL , 0, &(dwThreads[0]));
WaitForMultipleObjects(1, hThreadArray, TRUE, INFINITE);
CloseHandle(hThreadArray[0]);
请记住,我知道使用函数_th()调用多个线程不会使其并行化,这只是一个测试,因为我得到了非常奇怪的结果,所以我决定看看使用相同代码的一个线程和一个函数会发生什么
我在Intel Atom N270和windows XP中使用NUMPROC=1进行了测试
结果:
序列号:1485毫秒
单线程:425毫秒
我在使用多处理器机器时也得到了类似的结果,甚至代码使用信号量来并行化线程所做的工作
有人知道会发生什么吗
编辑
颠倒顺序,每次运行多次,等等…->不变
更高的N->线程1按比例更快
使用QueryPerformanceCounter()->无更改
线程创建开销->应该使线程更慢,而不是更快
原始代码:这是一个
缓存命中问题。我怀疑你按照你在问题中描述的顺序做了基准测试。首先调用函数,然后调用线程。当您更详细地对此进行基准测试时,您将观察到原因:数据(sqrt)在缓存中可用,因此代码的执行速度将更快。
要验证的测试:
在调用线程之前,请运行函数()
两次甚至更频繁。
第二次调用函数将给出更快的结果
在函数之前调用线程,结果将显示相反的结果。
该函数将显示更好的结果
原因:所有的sqrt计算(或者至少很多)都可以在缓存中使用,不需要重新计算。这要快得多。可能您当前的线程(您在其中调用函数()
)优先级较低?您是否在一个程序执行中按顺序运行了两个测试?我怀疑数据缓存对vetor[]
access.1的影响。您是否尝试过颠倒顺序,先线程后函数?(缓存效应)2。你是怎么测量时间的?我试着倒计时,结果是一样的=/它可能是浮点运算的精确模式,例如sqrt
。我听说Intel Atom的FPU性能很差。(主线程和新用户创建的线程对于C运行时数学库有不同的模式?)我尝试了反转另一个,两个线程都运行了多次,得到了相同的结果。好吧,我确实使用了你的代码,并且做得很好。结果非常清楚。再说一遍:你是如何测量时间的?你能报告一下“function()”和function_th()
连续运行5次的时间吗?我实际上每个函数运行了5次,并得到了平均值。我测量的时间是“(双)时钟()/CLOCKS\u PER_second;”,然后从另一个中减去一个。clock()
分辨率不好。在threaded()。按照threadlees()。只调用一个线程。将n增加到更高的值,以减少由于只执行一次操作而导致的错误。并用于计时目的。也许有机会将结果添加到上面的问题中(编辑)。使用QueryPerformanceCounter()->线程化更快。更高的n->->线程化速度更快。封闭整个线程创建不应该改变任何东西,因为它应该使“线程一”更慢,同样在我最初的基准测试中,我想计算线程创建开销。
HANDLE hThreadArray[1];
DWORD dwThreads[1];
hThreadArray[0] = CreateThread(NULL, 0, function_th, NULL , 0, &(dwThreads[0]));
WaitForMultipleObjects(1, hThreadArray, TRUE, INFINITE);
CloseHandle(hThreadArray[0]);