[pthreads] у кого какие числа получаются и почему?
Пропускная способность памяти одна на всех.
lol:~/papko$ ./th 1
threads: 1
[1109244240] result = -1963181146, time= 13.0400
lol:~/papko$ ./th 2
threads: 2
[1113573712] result = -1963181146, time= 29.9200
[1105181008] result = -1963181146, time= 29.9200
lol:~/papko$ ./th 4
threads: 4
[1123293520] result = -1963181146, time= 74.4600
[1104308560] result = -1963181146, time= 74.4000
[1131686224] result = -1963181146, time= 79.9700
[1114900816] result = -1963181146, time= 79.9900
правильно объяснил почему
проверил на 4 dualcore opterons - у каждого камня свой контроллер памяти и свои банки.
---
блин, они же все один кусок памяти используют
---
msc060 ~ $ ./th 1
threads: 1
[1096280432] result = -1963181146, time= 30.8300
msc060 ~ $ ./th 2
threads: 2
[1103305072] result = -1963181146, time= 59.5300
[1094912368] result = -1963181146, time= 61.5700
msc060 ~ $ ./th 4
threads: 4
[1135204720] result = -1963181146, time= 130.9600
[1118419312] result = -1963181146, time= 154.7300
[1110026608] result = -1963181146, time= 157.2200
[1126812016] result = -1963181146, time= 160.1500
msc060 ~ $ ./th 8
threads: 8
[1146141040] result = -1963181146, time= 459.2400
[1112570224] result = -1963181146, time= 468.4400
[1095784816] result = -1963181146, time= 496.7900
[1129355632] result = -1963181146, time= 498.6500
[1104177520] result = -1963181146, time= 517.0300
[1087392112] result = -1963181146, time= 524.2600
[1137748336] result = -1963181146, time= 524.7600
[1120962928] result = -1963181146, time= 514.3800
интересный переход от 4 к 8
кстати, а планировщик действительно рюхает (2.6.26):
CPU states: cpu user nice system irq softirq iowait idle
total 48.5% 0.0% 0.4% 0.0% 0.1% 0.0% 50.9%
cpu00 0.0% 0.0% 0.0% 0.0% 0.8% 0.0% 99.1%
cpu01 100.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
cpu02 100.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
cpu03 0.9% 0.0% 2.7% 0.0% 0.0% 0.0% 96.3%
cpu04 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 100.0%
cpu05 100.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
cpu06 0.0% 0.0% 0.9% 0.0% 0.0% 0.0% 99.0%
cpu07 100.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
по одному процессу на один контроллер памяти.
охх, спасибо всем, мне это конечно совсем не нравится, но придётся смириться...
Похоже, очень похоже. Смотри не абсолютные цифры (у меня быстрая десктопная память а коэффициент снижения скорости работы. Как и следовало ожидать, хорошо оптимизированный встроенный контроллер памяти оптеронов зарулил и вплоть до 4 тредов показатели ухудшения у оптеронов существенно ниже.
я как раз исправился - раз все треды используют один кусок памяти (который принадлежит одному процессору то всё равно всё упирается в одну шину.
Вообщето тут неплохо бы было приводить ещё и ассемблер ф-ции th_func, так как достаточно разумный компилятор мог бы все три цикла по i объединить в один, и в цикле по k осталось бы всего одно обращение на каждое i, а не три.
прога вот:у мя не запускается
edit: тьфу, там параемтр запуска нада, гадство что она не сообщает об этом
мой результ:
threads: 1
[2] result = -1963181146, time= 31.1600
threads: 2
[3] result = -1963181146, time= 62.7800
[2] result = -1963181146, time= 65.8700
threads: 4
[5] result = -1963181146, time= 158.1000
[3] result = -1963181146, time= 171.2900
[4] result = -1963181146, time= 173.8000
[2] result = -1963181146, time= 176.3300
threads: 8
[5] result = -1963181146, time= 620.4200
[9] result = -1963181146, time= 625.8600
[8] result = -1963181146, time= 646.7900
[3] result = -1963181146, time= 647.8800
[2] result = -1963181146, time= 678.8100
[6] result = -1963181146, time= 679.8500
[7] result = -1963181146, time= 683.5900
[4] result = -1963181146, time= 684.0400
--- th.cpp 2008-11-26 19:35:37.000000000 +0300
+++ th.cpp 2008-11-27 10:37:33.921256509 +0300
@@ -52,6 +52,12 @@
int main(int argc, char * argv[])
{
+ if (2 > argc)
+ {
+ printf("Usage: %s threads_num\n", argv[0]);
+ return -1;
+ }
+
int threads_num = atoi(argv[1]);
printf("threads: %d\n", threads_num);
> patch -i th.patch th.cpp
Looks like a unified context diff.
done
> g++ -O3 -lpthread th.cpp
> ./a.out
Usage: ./a.out threads_num
если вместо ::clock использовать ::gettimeofday числа совсеееем другие получаются...
если вместо ::clock использовать ::gettimeofday числа совсеееем другие получаются...Да, смешно получилось. Ситуация, когда секундомер в руках будет показывать другие цифры.
NAME
clock - Determine processor time
SYNOPSIS
#include <time.h>
clock_t clock(void);
DESCRIPTION
The clock function returns an approximation of [b]processor time[/b] used by the program.
Готова задачка на собеседование.
(ну т.е. если комп с юникс-окружением дать на решение, то нормально).
просто прежде чем использовать вызов, нужно ман-страницу по нему прочитать.
я вот вчера поленился, так бы может даже в форум не написали, если бы двумя головами его распарсили.
и есть шанс, что мы (ты? ? я?) еще чего-то очень важного не понимаем.
возвращает PTHREAD_SCOPE_SYSTEM, а с другой стороны clock-и считаются per-process.
хотя да, из этого можно сделать вывод о совместимости clock и мультитредности, наверное.
я вот вчера поленился, так бы может даже в форум не написали, если бы двумя головами его распарсили.Так дело-то в лени как раз на самом очевидном месте.
Назовись эта функция «clock_t dfghjkluytr», полезли бы в ман, а в очевидном варианте каждый считает себя знатоком АПИ.
Ты время меряешь clock-ом? Он же некорректно работает в многотредовом окружении. Исправляй на times (man times).
хотя в списке откровенно немультитредных функций (вроде strerror) её не встречал, потому и думал что всё окей
не лазить же в man за каждым вызовом printf?
нынче меряю разницей в вызовах gettimeofday до и после
если вместо ::clock использовать ::gettimeofday числа совсеееем другие получаются...вот что получается
threads: 1
[2] result = -1963181146, time= 30387
threads: 2
[2] result = -1963181146, time= 35663
[3] result = -1963181146, time= 38828
threads: 4
[2] result = -1963181146, time= 45166
[5] result = -1963181146, time= 45411
[3] result = -1963181146, time= 46488
[4] result = -1963181146, time= 49524
threads: 8
[6] result = -1963181146, time= 64003
[8] result = -1963181146, time= 81388
[3] result = -1963181146, time= 82175
[9] result = -1963181146, time= 85411
[4] result = -1963181146, time= 85963
[5] result = -1963181146, time= 92912
[7] result = -1963181146, time= 93286
[2] result = -1963181146, time= 96867
вставил там вместо клока
< clock_t beg = clock;
---
> struct timeval tv;
> gettimeofday(&tv, NULL);
> long beg = (tv.tv_sec*1000) + (tv.tv_usec / 1000);
< beg = clock - beg;
---
> long end = (tv.tv_sec*1000) + (tv.tv_usec / 1000);
> beg = end - beg;
> // beg = clock - beg;
< printf("[%d] result = %d, time= %.4f\n", (int)pthread_self result, beg/(double)1000000);
---
> printf("[%d] result = %d, time= %ld\n", (int)pthread_self result, beg);
т.е. вывод стал в миллисекундах
P.S.
для 8 запускал попозже, там тачка занята была, поэтому так медленно и неоднозначно вышло
> psrinfo -v
Status of virtual processor 0 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:13.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 1 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:16.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 2 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:18.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 3 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:20.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 4 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:22.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 5 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:24.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 6 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:26.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Status of virtual processor 7 as of: 11/27/2008 14:06:09
on-line since 11/24/2007 11:31:28.
The i386 processor operates at 2600 MHz,
and has an i387 compatible floating point processor.
Оставить комментарий
margadon
в аттаче - простая программа под linux/g++ которая заполняет большой глобальный массив, потом в несколько потоков без блокировок по нему бегает и считает какую-то арифметическую ерунду.компилил её вот так:
g++ -O3 -lpthread -oth
у меня на двухпроцессорном сервере (2 ксеона, 4 ядра, три стабильно свободны) выдаёт
./th 1
threads: 1
[1082132800] result = -1963181146, time= 22.1900
./th 2
threads: 2
[1082132800] result = -1963181146, time= 51.6700
[1090525504] result = -1963181146, time= 52.6300
./th 4
threads: 4
[1082132800] result = -1963181146, time= 88.2000
[1098918208] result = -1963181146, time= 117.3100
[1107310912] result = -1963181146, time= 130.3400
[1090525504] result = -1963181146, time= 131.8100
будто не параллельно выполняются потоки, а последовательно...
кто-нибудь может это объяснить?!
а у вас какие числа получаются?
прога вот: