Эффективное количество потоков

Я хочу оптимизировать свой номер заявки потоков. Почти у всех их есть IO около использования ЦП в равном значении. Сколько эффективное количество потоков, когда нет никаких других приложений, работающих в системе. Я хочу ответ для Windows и под JVM.

7
задан Shayan 3 February 2010 в 16:03
поделиться

6 ответов

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

Некоторые общие советы по многопоточности:

  • Вы не можете ускорить, как задачи, с большим количеством потоков; исключение состоит в том, что если у вас несколько процессоров, вы можете распараллеливать вычислительные задачи, используя один поток на каждый процессор, при условии, что эта логика может быть разделена так, что ее не обязательно выполнять последовательно.Хорошим примером для этого может быть задача «разделяй и властвуй», такая как сортировка слиянием, где две половины могут быть отсортированы в любом порядке.

  • Вы можете добиться некоторого ускорения за счет распараллеливания задач, которые не используют одну и ту же часть машины. Итак, учитывая, что вы говорите, что у вас «равное значение» ввода-вывода и вычислительных задач, вы захотите разделить их на разные потоки - опять же, это предполагает, что порядок не важен.

Если это так (как и во многих приложениях), когда потоки выполняют некоторую вычислительную логику, за которой следует некоторый ввод-вывод (например, запись данных на диск или на сервер базы данных), тогда будет очень сложно придумать с некоторой формулой для определения точного количества потоков, которое у вас должно быть, поскольку это будет сильно зависеть от данных, которые вы обрабатываете, от того, как вы их обрабатываете и что вы делаете с ними, когда обработка завершена. Вот почему лучше всего иметь настраиваемый пул потоков, размер которого можно легко регулировать, а затем запустить несколько нагрузочных тестов с разными размерами и посмотреть, какой из них работает лучше всего.

12
ответ дан 6 December 2019 в 06:50
поделиться

Я думаю, что что-то в этом роде сработает, если предположить, что названия перечислений следуют схожему образцу:

public D Map<D, S>(S enumValue, D defaultValue)
    {

        D se = defaultValue; 
        string n = Enum.GetName(typeof(S), enumValue);

        string[] s = Enum.GetNames(typeof(S));
        string[] d = Enum.GetNames(typeof(D));
        foreach (var v in d)
        {
            if (n.Substring(1, n.Length - 1) == v.Substring(1, v.Length - 1))
            {
                se = (D)Enum.Parse(typeof(D), v);
                break;
            }
        }
        return se;
    }

Варианты 2 будут состоять в том, чтобы создать словарь ints для отображения..

DestEnum de = DestEnum.DNone;
        SourceEnum se = SourceEnum.SA;
        Dictionary<int, int> maps = new Dictionary<int, int>();
        maps.Add((int)SourceEnum.SNone, (int)DestEnum.DNone);
        maps.Add((int)SourceEnum.SAB, (int)(DestEnum.DA | DestEnum.DB));
        maps.Add((int)SourceEnum.SA, (int)DestEnum.DA);
        de = (DestEnum)maps[(int)se];
-121--4407491-

Есть разница, когда вы подкласс Foo:

public class Bar extends Foo {

}

затем попытаться в другом пакете:

new Bar().getIntProperty ()

Он будет компилировать во втором из ваших примеров (все методы открытые), но не в первом (все методы доступ по умолчанию)

-121--4903948-

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

(Извините за любые проблемы с орфографией/форматированием, я ввел это без телефона)

0
ответ дан 6 December 2019 в 06:50
поделиться

Книга Java Concurrency in Practice содержит приблизительную формулу для определения размера пула потоков для сохранения определенной загрузки ЦП:

N = количество ЦП

U = целевая загрузка ЦП, 0 < = U < = 1

W/C = отношение времени ожидания для вычисления время

Оптимальный размер пула (количество потоков) для хранения процессоров в требуемое использование:

PoolSize = N * U * (1 + (W/C))

Это только для загрузки ЦП.

Вы можете получить доступные процессоры с помощью Runtime.getRuntime () .availureProcessors ()

-121--3787454-

Я не думаю, что на это есть окончательный ответ. Я бы просто предложил попробовать ваше приложение с разным количеством потоков и увидеть, что работает лучше всего. Одним из мест для запуска будет один поток больше, чем количество потоков процессора в вашем оборудовании, например, если у вас есть двухъядерный процессор с одним потоком на ядро, то используйте 3 потока.

2
ответ дан 6 December 2019 в 06:50
поделиться

Я обнаружил, что лучший способ справиться с этим - не использовать потоки напрямую, а использовать среду Executor. Вы можете экспериментировать с различными конфигурациями, но я обнаружил, что мне нравится CallerRunsPolicy.

1
ответ дан 6 December 2019 в 06:50
поделиться

Книга Java Concurrency in Practice дает приблизительную формулу для определения размера пула потоков, чтобы ваши процессоры были привязаны к определенному использованию:

N = количество ЦП

U = целевая загрузка ЦП, 0 <= U <= 1

W / C = отношение времени ожидания к вычислению времени

Оптимальный размер пула (количество потоков) для сохранения процессоров с желаемой загрузкой:

PoolSize = N * U * (1 + (W / C))

Это это только для загрузки процессора.

Вы можете получить доступные процессоры с помощью Runtime.getRuntime (). AvailableProcessors ()

9
ответ дан 6 December 2019 в 06:50
поделиться

Производительность - далеко не единственная причина использования потоков.

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

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

2
ответ дан 6 December 2019 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: