Подтвердить что ты не робот

Многопоточная Java не ускоряется

Я реализовал простой алгоритм сортировки параллельных слияний в Java. Это разрезает массив на равные части и передает их для сортировки независимо по каждому потоку. После сортировки сегментов массива они объединяются одним потоком. Поскольку нет общих ресурсов, поэтому синхронизация не используется при сортировке подписок. Последний поток, который объединяет массив результатов, ждет завершения остальных потоков.

Когда используются два потока, производительность достигает почти 66%. Когда я использую 4 потока, тогда время не отличается от версии 2 потоков. Я нахожусь в linux 2.6.40.6-0.fc15.i686.PAE и Intel Core i5.

Я сравниваю время с командой unix time (массиву присваиваются единые случайные целые числа). В конце сортировки я проверяю, правильно ли упорядочен массив (не параллельный).

1 Тема
$ echo "100000000" | time -p java mergeSortTest

Enter n: 
[SUCCESS]

real 40.73
user 40.86
sys 0.22

2 Темы
$ echo "100000000" | time -p java mergeSortTest

Enter n: 
[SUCCESS]

real 26.90
user 49.65
sys 0.48

4 Темы
$ echo "100000000" | time -p java mergeSortTest

Enter n: 
[SUCCESS]

real 25.13
user 76.53
sys 0.43

Использование ЦП составляет от 80% до 90% при использовании 4 потоков и около 50% при использовании 2 потоков и около 25% при использовании одного потока.

Я ожидал некоторого ускорения при запуске в 4 потоках. Я где-то не прав.

ОБНОВЛЕНИЕ 1

Вот код: http://pastebin.com/9hQPhCa8

ОБНОВЛЕНИЕ 2 У меня процессор второго поколения Intel Core i5.

Вывод cat /proc/cpuinfo | less (отображается только ядро ​​0).

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 42
model name      : Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
stepping        : 7
cpu MHz         : 800.000
cache size      : 3072 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx rdtscp lm constant_tsc arch_perfmon pebs bts xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 x2apic popcnt xsave avx lahf_lm ida arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
bogomips        : 4589.60
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
4b9b3361

Ответ 1

Core i5 имеет 2 ядра и технологию гиперпоточности, поэтому кажется, что у нее 4 ядра. Эти дополнительные два логических ядра не помогут почти столько же, сколько два физических ядра, так как ваш алгоритм сортировки хорошо справляется с тем, что CPU занят.

Поскольку вы попросили "достоверный" источник, я укажу на статью с веб-сайта Intel, которую я прочитал некоторое время назад: performance-insights-to-intel-hyper-threading-technology. В частности, обратите внимание на следующий раздел "Ограничения гиперпотока":

Исключительно эффективные для вычисления приложения. Если выполнение процессора ресурсы уже хорошо используются, тогда полученных благодаря технологии Intel HT. Например, код, который уже выполнить четыре команды за цикл не увеличится производительности при работе с технологией Intel HT Technology, поскольку Ядро процесса может выполнять только четыре команды в цикл.

Также обратите внимание на этот раздел о конкуренции подсистемы памяти:

Чрезвычайно большие приложения с пропускной способностью памяти. Технология Intel HT повышает спрос на подсистему памяти при запуске двух потоки. Если приложение способно использовать всю память пропускная способность с технологией Intel HT отключена, тогда производительность не будет увеличиваться при включении технологии Intel HT. Возможно в некоторых случаях производительность ухудшится из-за увеличения требования к памяти и/или кеширование данных в этих случаях. Хорошей новостью является то, что системы, основанные на ядре Nehalem с интегрированными контроллеров памяти и межкомпонентных соединений Intel® QuickPath увеличить доступную пропускную способность памяти по сравнению с более старыми процессорами Intel с технологией Intel HT. В результате число приложения, которые будут испытывать деградацию с использованием Intel HT Технология ядра Nehalem из-за отсутствия пропускной способности памяти значительно сокращается.

Другие интересные моменты можно найти в Intel Guide for Developing Multithreaded Applications. Вот еще один фрагмент из detecting-memory-bandwidth-saturation-in-threaded-applications:

Поскольку все большее число потоков или процессов ресурсов емкости кэша и пропускной способности памяти, масштабируемость приложение с резьбой может стать ограниченным. Память интенсивного потоковые приложения могут страдать от насыщения полосы пропускания памяти, как вводится больше потоков. В таких случаях резьбовое приложение не будет масштабироваться, как ожидалось, и производительность может быть уменьшена.

Ответ 2

Серия intel core i5-xxM имеет 2 ядра, поэтому использование более 2 потоков уменьшит производительность из-за большего переключения контекста.

Edit:

Вот расширение моего ответа, в котором я рассматриваю Core i7 architecture - конкретные факторы, которые могут повлиять на производительность процессора и интенсивной памяти такие операции, как сортировка.

Технология Turbo boost

Intel Core i7 имеет переменную частоту процессора. При высоких нагрузках частота будет ограничена теплом, что уменьшит прирост производительности при использовании большего количества сердечников.

Общий кеш L3

Сортировка больших наборов данных ( → 8 Мб) приведет к большому количеству сбоев страницы L3. Использование слишком большого количества потоков может увеличить количество ошибок страницы, что снижает эффективность. Я не уверен, так ли это в случае слияния. (Кстати: как вы измеряете промахи кэша L3 в Linux?) Я не уверен, что это фактор.

Я должен сказать, что я удивлен, что вы не получаете повышения производительности от использования всех четырех ядер i7. Я попробую провести некоторые тесты дома в эти выходные.

Ответ 3

Другой возможной проблемой может быть ложный обмен.

http://en.wikipedia.org/wiki/False_sharing

http://drdobbs.com/go-parallel/article/showArticle.jhtml?articleID=217500206

Это будет зависеть от того, как часто слияние сортирует доступ к элементам в строках пограничного кэша. Это, вероятно, будет гораздо более заметным на наборах данных, меньших, чем килобайт или около того.

Ответ 4

Я пробовал это на i7, и даже с 4 ядрами не было улучшения от 2 - 4 потоков. Я подозреваю, что проблема в том, что ваши данные не вписываются в кеш, поэтому вы проверяете пропускную способность одной шины памяти.

Ответ 5

Я получаю ожидаемый результат на двухъядерном i7 с опцией -server JVM, 100000000 int и 2GB Xmx-памятью:

1 поток: 23 секунды
2 темы: 14 секунд
4 потока: 10 секунд

И я также удалил сборку мусора вручную и выполнил сортировки последовательно в одном экземпляре JVM, сначала получив разминки.

Как отмечает Мистер Смит, микрообъектизация (JVM hotspot) несколько сложна, и я могу добавить, что для ячеек 4+ сортировка слияния может выполняться наполовину количеством потоков, противоположных одному потоку, как сейчас, поэтому ваш эталон не полностью соответствует многопоточному подходу.

Вы также можете проверить этот вопрос.

Ответ 6

В качестве сравнения попробуйте использовать сортировку слияния с java 7 и картой соединения fork. Ниже приведен пример того, как это сделать здесь. Это покажет вам, если это проблема с вашей реализацией или ограничение машины.

Ответ 7

Интересно, потому что у меня такое же наблюдение при попытке параллелизации сортировки слияния. Пробовал два разных подхода к нерестам, но не получил ускорения. Мой подход к параллелизации сортировки слияния заключается в том, чтобы сделать слияние параллельным. и делать отдельные слияния на разных ядрах? В этом случае отрезок рекурсии и количество потоков влияют на скорость. Опять же, скорость не может превышать последовательную скорость. Этот метод появляется в книге "Структурированные параллельные программы по шаблонам и практике" от Моргана Кауфмана.

Параллельный сортировка слияния

Ответ 8

Мне недавно пришлось сделать papper, сравнивая сортировку пузырьков, сортировку слияния и bitonic sort на архитектуре i7. Я использовал первый код, приведенный здесь для слияния, и имел ту же проблему: 8threads были не лучше 4. Затем я прочитал материал SMT (intel hyperthreading) и выяснил проблему и решение:

Удалите эти строки по методу слияния:

if (Runtime.getRuntime(). freeMemory() < ((n1 + n2) * 4))           Runtime.getRuntime(). gc();

Этот код освобождает уровни памяти L1 и L2 в физических ядрах, но в этих kbs у нас есть буферы для двух логических потоков (не только один), поэтому один поток стирает буфер потока сестер в этом физическом ядре.

После удаления, если, я видел улучшение 1.25 между 4 и 8 потоками, которые предоставляет SMT. Если кто-то может попробовать это на i5, это будет здорово.