2012-02-13 5 views
1

У меня есть большой массив в ОЗУ и вы хотите как можно быстрее прочитать данные из него. Игнорируйте любую возможную синхронизацию, я только задаюсь вопросом о теории.Увеличивает ли производительность многопоточности доступ к памяти?

Быстрее ли распространять эти чтения по нескольким потокам, чем просто использовать один?

Редактировать: точки данных составляют около 20 КБ каждый, и я не могу предсказать, в каком порядке они считываются.

ответ

1

Вообще говоря: да, но Остерегайтесь недостатков в кэше.

Предположим, что у вас есть int []: рассмотрим разбиение его в диапазонах последующих элементов и каждый поток получит собственный диапазон (thread1 получает от 0 до 127, thread2 от 128 до 255, ...) ,

Когда вы читаете один элемент массива, ядро ​​процессора, выполняющее нагрузку, скорее всего, загрузит некоторые из последовательных элементов массива в кеш , потому что в большинстве случаев они понадобятся в правильном порядке after (immagine для (int i = 0 ;; i ++) do (arra [i])): если вы не разделите свои данные в грубым способом, вся эта работа будет потрачена впустую.

Вы можете прочитать об этом в следующих статьях из Джо Даффи:

Не строго родственный: The 'premature optimization is evil' myth, в частности, часть «Понять порядок что имеет значение «

Как сказано в сообщении @Alex, общее правило заключается в том, что у вас есть всегда измеряют и никогда не предполагают ничего: эффективная масштабируемость через параллелизм является сложной задачей и требует много глубокого понимания базовой архитектуры.

+2

Я не думаю, что локальность данных очень полезна, так как мои элементы большие и доступны случайным образом. Но означает ли это, что соединение между процессором и памятью позволяет выполнять параллельное выполнение чтения, если данные существуют в разных частях памяти? – Daniel

+0

Ну, если ваши данные указывают этот размер, ответ определенно да! Не забудьте проложить элементы массива до ближайшего кратного размера слова процессора (смещение может быть значительным когда-то). – Maghis

+0

Имеет ли связь между процессором и памятью возможность параллельного выполнения чтения, если данные существуют в разных частях памяти? – Daniel

0

Технически да. Вы можете использовать больше потоков для чтения из разных мест в памяти. Процессор быстрее, поэтому он может выдавать много чтений, например, один читать на поток, пока не вернется результат от первого чтения. Затем начните обработку запросов. Это работает, если ОЗУ не блокируется; т.е. поддерживает сразу несколько считываний. Например, у вашей памяти есть только 1 входная линия и 1 выходная линия, тогда она будет блокировать, и никакое количество потоков не поможет.

Теперь имейте в виду, что именно вы делаете с данными, которые вы читаете. Если вы отправляете его по сети синхронно или выгружаете на жесткий диск, это не обязательно означает, что вы должны использовать многопоточность для чтения данных, поскольку это будет узким местом для write_to_HDD/sendData.

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

0

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

Измерьте производительность, не догадывайтесь.

+0

Я сделал простой тест, и результаты неубедительны - иногда я получаю прибыль от производительности, а в других случаях абсолютно ничего. Вот почему я хотел знать теорию. – Daniel

+1

Рассматривали ли вы «джит-разогрев» и сравнимые/измеримые тестовые прогоны? Если вы можете опубликовать свой тестовый код, который бы точно помог. – Alex

+0

Да, этот тест может определенно использовать некоторые улучшения с надлежащим прогревом JIT и усреднением в течение нескольких тестовых прогонов. Код довольно уродливый, на самом деле не хотел бы распространять его, но я сделаю эти изменения и снова проведу тест. Благодаря! – Daniel

Смежные вопросы