Используйте оператор Distinct:
var idList = yourList.Select(x=> x.ID).Distinct();
Предположим, dostuff
выполняется на одном процессоре. Он записывает данные в канал, и эти данные будут в кеше на этом процессоре. Поскольку filterstuff
читает из этого канала, планировщик решает запустить его на том же ЦП, так что его входные данные уже находятся в кеше.
Если ваше ядро построено с CONFIG_SCHED_DEBUG = y
,
# echo NO_SYNC_WAKEUPS > /sys/kernel/debug/sched_features
должны отключить этот класс эвристики. (См. /usr/src/linux/kernel/sched_features.h
и / proc / sys / kernel / sched _ *
для других настроек планировщика.)
Если это помогает, и проблема все еще возникает с более новым ядром, и оно действительно быстрее работает на отдельных процессорах, чем на одном процессоре, сообщите о проблеме в список рассылки ядра Linux, чтобы они могли скорректировать свои эвристики.
Попробуйте установить привязку процессора (процессора):
taskset -c 0 dostuff | taskset -c 1 filterstuff
Изменить:
Попробуйте этот эксперимент:
создайте файл с именем proctest и chmod + x proctest
со следующим содержанием:
#! / bin / bash
пока правда
делать
пс
спать 2
сделанный
запустить это:
./ proctest | grep bash
ps u
start top -p
со списком PID нескольких процессов с наивысшим уровнем, скажем 8 из них, из списка, оставленного на экране после выхода top
, а также для proctest
и grep
, которые были перечислены ps
- все через запятую, например (порядок не имеет значения):
top -p 1234, 1255, 1211, 1212, 1270, 1275, 1261, 1250, 16521, 16522
.09
и нажмите Введите , чтобы установить короткое время задержки proctest
и grep
не работают, иногда на одном процессоре, иногда на разных The Linux scheduler is designed to give maximum throughput, not do what you imagine is best. If you're running processes which are connected with a pipe, in all likelihood, one of them is blocking the other, then they swap over. Running them on separate cores would achieve little or nothing, so it doesn't.
If you have two tasks which are both genuinely ready to run on the CPU, I'd expect to see them scheduled on different cores (at some point).
My guess is, what happens is that dostuff runs until the pipe buffer becomes full, at which point it can't run any more, so the "filterstuff" process runs, but it runs for such a short time that dostuff doesn't get rescheduled until filterstuff has finished filtering the entire pipe buffer, at which point dostuff then gets scheduled again.