@Shahelm

Почему не утилизируются полностью все ядра процессора?

Суть вопроса почему не утилизируются полностью все ядра процессора, одно ядро загружено на 100% остальные периодически 0-30%. Я предполагал что задачи будут распределятся равномерно между всеми доступными потоками (в моем случае 8) при запуске tokio с runtime 'Threaded Scheduler' и запуске задач с помощью tokio:spawn.

Запускаю на: Intel(R) Core(TM) i7-3770 CPU

Коротко что происходит в коде:
Создается 100 000 задач (tokio::spawn), каждая задача это sql запрос к mysql который возвращает какие-то строки, считаем общие количество строк.

Dependencies:
mysql_async = "0.24.0-alpha"
dotenv = "0.15.0"
tokio = { version = "0.2.21", features = ["full"] }

use std::env;
use std::sync::Arc;

use mysql_async::{Pool, Error};
use mysql_async::prelude::*;

#[tokio::main]
async fn main() {
    dotenv::dotenv().ok();

    let pool = get_pool();
    let product_ids: Arc<Vec<u64>> = Arc::new(get_product_ids());

    let mut tasks = Vec::with_capacity(100002);

    let start = Instant::now();

    for _ in 1..=100000 {
        tasks.push(
            tokio::spawn(
                get_product(pool.clone(), product_ids.clone())
            )
        );
    }

    let mut number_of_products = 0;

    for result in tasks {
        number_of_products += result.await.unwrap().unwrap().len();
    }
}

fn get_pool() -> Pool {
    return mysql_async::Pool::new(env::var("DATABASE").expect("Failed to create connection pool");
}

async fn get_product(pool: Pool, product_ids: Arc<Vec<u64>>) -> Result<Vec<u64>, Error> {
    let mut connection = pool.get_conn().await.expect("Failed to get connection from pool");

    let query = format!(
        "SELECT product_id FROM products where product_id IN ({})",
        get_place_holders(product_ids.len())
    );

    connection
        .exec(query.as_str(), product_ids.as_ref())
        .await
}

fn get_place_holders(number_of_items: usize) -> String {
    vec!["?".to_string(); number_of_items].join(",")
}

fn get_product_ids() -> Vec<u64> {
    vec![123, 1234, 12345]
}

Еще немного информации:
uname -a:
Linux ubuntu 4.10.0-38-generic #42~16.04.1-Ubuntu SMP Tue Oct 10 16:32:20 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Собираю с помощью команды:
cargo build --release

Дополнительно пробовал увеличить параметры:
  • tokio core_threads
  • mysql_async pool_max
  • Вопрос задан
  • 157 просмотров
Пригласить эксперта
Ответы на вопрос 3
@Shahelm Автор вопроса
Я разобрался, все банально я не правильно интерпретировал вывод htop, он при отрисовки дерева процесса выводит суммарную информацию по потреблению CPU в главном процессе.

Всем спасибо.
Ответ написан
Комментировать
sgjurano
@sgjurano
Разработчик
А сама база то справляется? А то вы вполне могли в неё упереться.
Ответ написан
sarapinit
@sarapinit
Точу водой камень
Скорее всего потоки ждут завершения IO операций (получение по сети данных от БД). Я не знаю Rust, но ситуация неполной утилизации ЦП, специфичная для асинхронного кода.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы