Я разработал простой инструмент для переноса данных. используя 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. Даже я пытался прикрепить все процессы к одному и тому же ядру, но не вижу никаких изменений.
спасибо