首先写了一个找第N个素数的程序,使用很原始的算法,然后设定为找第10000个素数。
我本意是想弄一个线程来记录当前的搜索进度,这样就涉及两个变量,当前已经找到了第几个素数,以及当前正在测试的数。为了保证正确记录这两个变量,就弄了一个信号量来设定临界区。
于是奇异的现象就出现了,没有设置信号量之前整个程序运行时间是12.3秒左右,而使用了信号量之后,速度竟然降低到11.8秒左右,速度提高近5%。虽然不是每次测试都快0.5秒,但如果没有快0.5秒的话,就是差不多12.3秒。只会出现基本上速度相同,或者快0.5秒的情况看。
明明是加了信号量,需要内核去做一些事情,这些事情多多少少也会吃掉一些时间,如果说内核调用速度很快对运行速度基本上没有影响,那么有没有使用信号量的时间基本上一样也就算了,但问题是加了信号量之后运行速度竟然更快了,这也太诡异了的说。
随后我又给另一个代码段加了一个信号量,但是速度并没有变得比11.8秒更快,似乎11.8秒就是极限了
原因不明,先把这个现象记录下来好了。
gs@yts-j:~/pg$ time ./ss && time ./ss_lock && time ./ss && time ./ss_lock
real 0m12.212s
user 0m11.730s
sys 0m0.000s
real 0m11.831s
user 0m11.355s
sys 0m0.001s
real 0m12.315s
user 0m11.729s
sys 0m0.002s
real 0m11.829s
user 0m11.356s
sys 0m0.002s
gs@yts-j:~/pg$ time ./ss && time ./ss_lock && time ./ss_lock2 && time ./ss && time ./ss_lock && time ./ss_lock2
real 0m12.239s
user 0m11.732s
sys 0m0.002s
real 0m11.860s
user 0m11.361s
sys 0m0.003s
real 0m11.865s
user 0m11.365s
sys 0m0.002s
real 0m12.240s
user 0m11.735s
sys 0m0.000s
real 0m11.857s
user 0m11.361s
sys 0m0.001s
real 0m11.861s
user 0m11.365s
sys 0m0.003s
#include
#include
#include
void ss();
void info();
int target_pos;
int target_num;
int current;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
int main(){
target_num = target_pos = 1;
current = 3;
//printf("%d\n", 'g');
ss();
return 0;
}
void ss(){
while (target_pos < 10000) {
pthread_mutex_lock(&lock2);
unsigned int i;
int is_ss;
is_ss = 1;
for (i = 3; i < current; i += 2) {
if (current % i == 0) {
is_ss = 0;
break;
}
}
if (is_ss) {
//pthread_mutex_lock(&lock);
target_pos++;
target_num = current;
//pthread_mutex_unlock(&lock);
}
current += 2;
pthread_mutex_unlock(&lock2);
}
}
void info(){
for (;;) {
printf("%u, %u\n", target_pos, current);
sleep(1);
}
}
—————-2011年7月31日更新————–
现在我想我知道原因了。猜测的原因如下:
使用了线程锁给核心循环加锁以后,内核就不会在程序取得锁的时候对程序进行上下文切换,这样减少了上下文切换造成的开销,于是程序总体运行时间在用户看来是更快了。
用锁来企图加速程序是不现实的,之所以在这里能观察到明显的程序加速现象,是因为这个程序太小,相对于内核切换上下文来说,还是上下文切换的开销更大,所以才能观察到明显的程序加速的现象。
F-22's Trace
greensea 的个人主页
sky-city
极夜奁
小樱之町