Улучшить параллелизм c # linq - PullRequest
0 голосов
/ 26 апреля 2018

Я разработал простой инструмент для переноса данных. используя C #, Linq и EF. Этот инструмент получает все данные, которые я хочу переместить из места A в B. Код выглядит примерно так:

var data = dataAccess.GetData()
 Parallel.ForEach(data, currentdata =>
 { 
   //Do some business, and insert data
 });

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

Итак, я попробовал этот инструмент с огромным объемом данных, и процесс миграции занимает около 5 часов.

Тогда я решил попробовать другую идею.

Я сгенерировал 4 consoles.exe этого проекта, внеся изменения, теперь каждый из них занимает четверть данных.

Например: общее количество данных для переноса составляет около 40 миллионов регистров, консоль 1 переносится с 0 до 10 м, консоль 2 с 10 до 20 м, консоль 3 с 20 до 30 м и консоль 4 с 30 до 40 м Затем я запустил эти консоли, по одному на каждое ядро ​​моего процессора, и угадайте, что для переноса всего потребуется меньше половины.

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

Есть идеи повторить это улучшение только с одной консолью?

Спасибо.

EDIT: Сейчас я пытаюсь это сделать, ранее я разбил данные на части:

Process process = Process.GetCurrentProcess();
            int cpuCount = Environment.ProcessorCount;
            int offset = process.Threads.Count;
            Thread[] threads = new Thread[cpuCount];
            for (int i = 0; i < cpuCount; ++i)
            {
                Thread t = new Thread(new ThreadStart( migrateChunk))
                { IsBackground = true };
                t.Start();
            }

            process.Refresh();
            for (int i = 0; i < cpuCount; ++i)
            {
                process.Threads[i + offset].ProcessorAffinity = (IntPtr)(i+1);
            }

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

1 Ответ

0 голосов
/ 27 апреля 2018

Проблема на

var data = dataAccess.GetData()

Пусть для извлечения 40 миллионов данных требуется 4 минуты, а для извлечения 10 миллионов данных - 1 минута, поэтому консольные приложения 10 миллионов начинают перемещать данные, когда 40 миллионов все еще извлекают данные из базы данных. .

 Parallel.ForEach(data, currentdata => { //Do some business, and insert data });

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...