В приведенном коде была создана тестовая реализация для обработки массива <i>vec01</i>. <br/> При изменении количества повторов этой обработки я наблюдаю за временем выполнения. <br/> Меня озадачивает, почему время выполнения иногда отличается более чем в три раза, например, значения <i>time_min = 41200 time_max = 145000</i>. <br/> Компьютер имеет 6 ядер и 12 потоков, и в данный момент не нагружен другими задачами. Если я не ошибся в коде, но при этом наблюдается периодическое "захватывание" <i>ресурсов потоков</i> компьютера, как можно решить эту проблему, чтобы время выполнения колебалось в пределах 20%? <br/> _play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=537d0482efc78c4a05a2174015c2291c <br/>
Для оптимизации кода и уменьшения колебаний во времени выполнения есть несколько стратегий, которые вы можете рассмотреть. Хотя у меня нет доступа к вашему конкретному коду, могу дать общие рекомендации по оптимизации, которые могут помочь: ### 1. **Параллелизм и многопоточность** - Используйте многопоточные библиотеки, такие как Rayon для Rust, чтобы распределить нагрузку по всем доступным ядрам. Это помогает эффективно использовать ресурсы процессора и сократить время обработки. ### 2. **Избегайте блокировок** - Если в вашем коде есть блокировки (например, использование Mutex), старайтесь по возможности свести к минимуму время, на которое блокируется общий ресурс. Исследуйте возможность использования "lock-free" структур данных. ### 3. **Избегайте невыгодных аллокаций** - Убедитесь, что ваше приложение не создает много временных объектов и не выполняет частые аллокации памяти. Используйте пул объектов или другие механизмы кэширования. ### 4. **Используйте профилирование** - Используйте инструменты профилирования, такие как `cargo flamegraph`, чтобы выявить узкие места в вашем коде. Это даст вам четкое представление о том, какие части вашего приложения требуют оптимизации. ### 5. **Оптимизация алгоритмов** - Проверьте алгоритмы, используемые в вашем коде. Иногда замена алгоритма на более эффективный может существенно уменьшить время выполнения. Например, это может быть уменьшение сложности с O(n^2) до O(n log n). ### 6. **Настройка параметров выполнения** - В зависимости от того, как вы запускаете обработку, возможно, стоит поиграть с параметрами выполнения. Например, увеличить размер пула потоков или настроить параметры системы. ### 7. **Минимизируйте взаимодействие с ОС** - Если ваша программа осуществляет много операций ввода-вывода, старайтесь минимизировать взаимодействие с файловой системой или сетью, так как эти операции могут существенно замедлять выполнение. ### 8. **Параметры компиляции** - Убедитесь, что вы компилируете с оптимизацией. Используйте `cargo build --release` для создания оптимизированной версии вашего приложения. ### 9. **Тестирование на разных данных** - Убедитесь, что данные, которые вы используете для тестирования, представляют собой заинтересованный набор. Случайные данные могут вести себя по-другому, чем заранее известные данные. ### 10. **Избегайте избыточности** - Проверьте, нет ли избыточных операций в вашем цикле обработки. Оптимизация мелких деталей может привести к значительному времени выполнения. Если вы предоставите конкретный код, я мог бы предложить более целенаправленные улучшения.
Не скажу ничего про алгоритм и корректность замеров, но время t01 и t02 ты точно измеряешь неправильно
subsec_nanos
Returns the fractional part of this Duration, in nanoseconds.
This method does not return the length of the duration when represented by nanoseconds. The returned number always represents a fractional portion of a second (i.e., it is less than one billion).
https://doc.rust-lang.org/std/time/struct.Duration...
У структуры Duration есть операторы для сравнения, так что тебе не обязательно знать конкретное число, пока ты не выводишь его в консоль
let mut t01 = Duration::MIN; let mut t02 = Duration::MAX; if duration> t01 { t01 = duration; // здесь } if duration< t02 { t02 = duration; // и здесь }
UPD:
Комп 6 ядер 12 потоков ничем не нагружен. Если не накосячил с кодом, а так
захватывается периодически ресурс потоков компа, то как такое решить
и получать расхождение в пределах 20%?
1. Такой разброс, как у тебя показан - это норма. Нужно смотреть не на минимум/максимум, а на распределение (в комментах скинул график - там тоже минимум и максимум сильно различаются, но прогонов с таким временем мало)
2. Я не увидел в вопросе описания того, как происходит запуск. Хотябы в --release компилировал?
3. У тебя данные вполне статичные, так что компилятор при желании мог очень много наоптимизировать, что даст тебе некорректные результаты, но на распределение это влиять не должно.
Возможно OC выдала вторичный поток - частично лечится повышением приоритета процесса или выставлением определённого ядра, например через process lasso.
Лучше создай массив вне цикла для хранения времени каждой итерации цикла и записывай туда, желательно не в куче [f32; N].
Следом после того, как программа завершит выполнение выведи свой массив и посмотри данные, по хорошему вывести среднее значение, но если важна каждая отдельная итерация, глазами поработать придётся.
А сейчас ты записываешь лишь последний результат.
P.S: Пересмотрел код, меряешь в наносекундах, а юзаешь вектор - который хранится в куче.
Вот тебе и ответ полагаю, перемести данные из кучи в стек, должно стать стабильнее.
И учти коммент: mayton2019
Сейчас ты меряешь какой-то случайный процесс который в общей своей массе длиннее
чем твой изучаемый алгоритм.
2. Я не увидел в вопросе описания того, как происходит запуск. Хотябы в --release компилировал?
спасибо за помощь разобраться
да, > cargo run --release
в отличие от debug даёт общее ускорение выполнения, но между повторами сохраняется иногда двукратное расхождение времени выполнения, например для массива на 10к элементов и 30 повторов:
При значительном увеличении кол-ва элементов в массиве, например, до 10кк:
вот гуляет время от 45 ms до 89 ms на одинаковых условиях и наборе данных и думаю, что это не нормально ( случайные служебные процессы ), а косяк кода. Поэтому задал вопрос.