Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>запускаю с периодичностью 60 ms загрузка проца с распараллеливанием 14% без 12.5 %
Судя по всему, у вас просто слишком мало нагрузки.
То, что вы описываете — это числмолотилка отрабатывает за 0мс, а 12.5% отъедает тот код, который у вас выполняется между вызовами.
Я вам настоятельно советую перестать мерить производительность по таск менеджеру, и начать использовать взрослые инструменты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Написал свой аналог класса Parallel — всё тоже самое — может дело в лямда выражениях и переменных
class MyParallel
{
private struct Work {
public Action<int> body;
public int start;
public int stop;
}
public static void For(int fromInclusive, int toExclusive, Action<int> body)
{
int noCpu = Environment.ProcessorCount;
Thread[]threads=new Thread[noCpu];
Work[] work = new Work[noCpu];
int Step=(toExclusive-fromInclusive)/noCpu;
for (int i = 0, Index=fromInclusive; i < noCpu; i++,Index+=Step)
{
threads[i] = new Thread(ParameterizedThreadStart);
work[i] = new Work();
work[i].start = Index;
work[i].stop = Index + Step;
work[i].body = body;
}
work[noCpu - 1].stop = toExclusive;
for (int i = 0; i < noCpu; i++)
threads[i].Start(work[i]);
for (int i = 0; i < noCpu; i++)
threads[i].Join();
}
private static void ParameterizedThreadStart(object obj)
{
for (int i = ((Work)obj).start; i < ((Work)obj).stop; i++)
((Work)obj).body(i);
}
}
VYR>Написал свой аналог класса Parallel — всё тоже самое — может дело в лямда выражениях и переменных
У меня вот с таким вариантом использования твоего метода For дает загрузку 100% всех ядер, а что у тебя за Body, нет ли там каких-то синхронизирующих элементов случаем,
например какой-нибудь вывод в UI
For(1, 1000000, (i) =>
{
double x = 0;
for (int j = 0; j < 100000; j++)
{
x = x + Math.Sin(j);
}
});
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Здравствуйте, okon, Вы писали:
O>У меня вот с таким вариантом использования твоего метода For дает загрузку 100% всех ядер, а что у тебя за Body, нет ли там каких-то синхронизирующих элементов случаем,
на X... мне загрузка всех ядер ...
ты хоть вопрос читал???
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Здравствуйте, okon, Вы писали:
O>>У меня вот с таким вариантом использования твоего метода For дает загрузку 100% всех ядер, а что у тебя за Body, нет ли там каких-то синхронизирующих элементов случаем,
VYR>на X... мне загрузка всех ядер ... VYR>ты хоть вопрос читал???
а С# паралелил при помощи Parallel.For — какая-то жуть — накидывает 5% нагрузки в лучшем случае
а иногда так глючит что распараллеленый код выполняется за большее количество времени
Т.е. я так понял у тебя задача выполнить паралельно за меньшее количество времени, чем одним потоком ?
По "закону сохранения энергии" это возможно только если ядра будут нагружены в сумме > 100%, например 26% каждое ядро.
а если хочется быстрее завершить задачу то надо использовать все 100%.
Как я сейчас понимаю ты не хочешь в 4 раза быстрее выполнить задачу, а просто хочешь каждое ядро по 25% нагрузить ?
Если так , то любая расчетная нагрузка будет занимать 100%, пока не выполнится.
Если у тебя там есть не только расчеты но и работа с устройствами, то надо смотреть как лучше.
Если хочется чтобы ядро немного "отдыхало" делай там Thread.Sleep(100) например или await Task.Delay(100) если используешь async/await.
For(1, 1000000, async (i) =>
{
double x = 0;
for (int j = 0; j < 1000; j++)
{
x = x + Math.Sin(j);
await Task.Delay(1);
}
});
Например вот так
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
если в С++ всё по честному (если распределил на 4 проца — то выполнится в 4 раза быстрее)
то в С# какой-то облом (если распределил на 4 проца то выполнится только в 3 раза быстрее (а то и в два))
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>В чём может быть ещё потеря производительности
VYR>если в С++ всё по честному (если распределил на 4 проца — то выполнится в 4 раза быстрее)
VYR>то в С# какой-то облом (если распределил на 4 проца то выполнится только в 3 раза быстрее (а то и в два))
GC, скорее всего. For Each, а также new double[], вот это всё. Можешь расчехлить Concurrency Visualizer и посмотреть.
VYR>если в С++ всё по честному (если распределил на 4 проца — то выполнится в 4 раза быстрее) VYR>то в С# какой-то облом (если распределил на 4 проца то выполнится только в 3 раза быстрее (а то и в два))
А еще не раскрыто что делает
obj.fs[ic].Next(obj.tmp[ic], obj.src);
Что в этом методе Next делается ?
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Ты можешь выложить код в самодостаточном виде, чтобы компилировался и запускался? Чтобы просто взять да посмотреть, что происходит. Иначе вся эта тема — пальцем в небо и гадание на кофейной гуще. Не понимаю, как другим удаётся советовать что-то осмысленное, не видя работающего кода.