Ускорение потоков и несуществующих ускорений в Linux SMP - PullRequest
1 голос
/ 17 февраля 2011

Я написал небольшой пример программы на C ++ с использованием boost :: thread.Поскольку в нем 215 строк, я разместил его на pastebin вместо

http://pastebin.com/LRZ24W7D

Программа создает большое количество операций с плавающей запятой (в настоящее время 1 ГБ) и добавляет их сначала последовательно, а затемиспользуя несколько потоков (размещенных внутри класса device_matrix).Предполагая, что машина является SMP, я ожидаю увидеть ускорение из кода.И на моей машине с Windows я вижу четырехкратное ускорение при использовании 4 экземпляров device_matrix (с четырьмя потоками на моем двухъядерном гиперпоточном процессоре Intel Core2).Вывод в Windows следующий:

starting computation
device_matrix count       4
elements                  268435456
UINT_MAX                  4294967295
data size total           1024 mb
size per device_matrix    256 mb
reference                 134224128.00000
result                    134224128.00000
time taken (init)         12.015 secs
time taken (single)       3.422 secs
time taken (device)       0.859 secs

Однако, когда я компилирую тот же код на имеющейся у меня машине с Ubuntu, я вижу следующий вывод:

starting computation
device_matrix count       8
elements                  268435456
UINT_MAX                  4294967295
data size total           1024 mb
size per device_matrix    128 mb
reference                 134215408.00000
result                    134215400.00000
time taken (init)         3.670 secs
time taken (single)       3.030 secs
time taken (threaded)     3.950 secs

Здесь,ускорение не наблюдается (на самом деле, оно намного медленнее).

Используемая мной машина Ubuntu имеет следующий вывод uname -a

Linux gpulab03 2.6.32-23-generic #37-Ubuntu SMP Fri Jun 11 08:03:28 UTC 2010 x86_64 GNU/Linux

И hwinfo -short даетследующий вывод:

cpu:
                       Intel(R) Core(TM) i7 CPU         930  @ 2.80GHz, 1600 MHz
                       ... 7 more times

который я читаю как компьютер с восемью ядрами (ну, четырехъядерный с HT)

Я использую следующую строку для компиляции моей программы в Windows:

cl /Fe"boost.exe" /EHsc -I. boost.cpp /link /LIBPATH:"C:\boost\boost_1_45_0\stage\lib"

А в Ubuntu я использую следующую строку:

g++ -O0 -v -o boost -I$HOME/Code/boost -L$HOME/Code/boost/stage/lib boost.cpp -lboost_thread-gcc44-mt

Вывод при запуске вышеуказанной строки здесь http://pastebin.com/Gj6W3pcs на случай, если он может кому-либо что-либо сказать.

Поскольку я не привык к разработке под Linux, я просто не уверен, что искать.Есть ли какой-то флаг, который мне нужно передать GCC, или какой-то параметр, который мне нужно где-то включить, чтобы получить реальные параллельные потоки?

Я искал в сети пример программы, использующей boost :: thread, который могдайте мне что-то для сравнения, но я нахожу только небольшие примеры производителей-потребителей, которым не нужно ничего «тяжелого» хруста.

В качестве дополнительной вещи, используя команду времени, с одним потокомв следующий раз (на всякий случай, когда boost :: timer не работает):

real    0m9.788s
user    0m9.500s
sys     0m0.280s

И при использовании 8 потоков я вижу следующее:

real    0m7.292s
user    0m10.340s
sys     0m0.340s

Что не похоже нав любом случае указывать на более быстрый запуск.

Я должен также упомянуть, что я нахожусь на обычной учетной записи пользователя, и я построил буст сам (и поэтому, для этой цели связываюсь с ним вне «обычных» папокв Linux.) Это также означает, что я строго ограничен в том, что я могу установить, и т. д. Существуют ли аналогичные ограничения, которые так или иначе применяются к потокам?

1 Ответ

2 голосов
/ 18 февраля 2011

Я считаю, что проблема с boost::timer. Если я использую gettimeofday и получаю вычитание, я получаю другие результаты синхронизации.

Похоже, что clock(), то, что boost::timer использует, возвращает количество процессорного времени, используемого всей программой, а не только одним потоком. Для меня это похоже на ошибку Boost.

Я сделал новую версию вашего кода, совместимую с Boost на компьютере с CentOS 5. Я изменил вашу операцию do_sum в свободную функцию, так что мне было гарантировано, что сумма была вычислена одинаково для одиночной и многопоточной. Я добавил заголовок, отличный от Windows, чтобы использовать gettimeofday.

Код здесь.

...