| 895 | } |
| 896 | |
| 897 | pub fn codec_thread_num(limit: usize) -> usize { |
| 898 | let max: usize = num_cpus::get(); |
| 899 | let mut res; |
| 900 | let info; |
| 901 | let mut s = System::new(); |
| 902 | s.refresh_memory(); |
| 903 | let memory = s.available_memory() / 1024 / 1024 / 1024; |
| 904 | #[cfg(windows)] |
| 905 | { |
| 906 | res = 0; |
| 907 | let percent = hbb_common::platform::windows::cpu_uage_one_minute(); |
| 908 | info = format!("cpu usage: {:?}", percent); |
| 909 | if let Some(pecent) = percent { |
| 910 | if pecent < 100.0 { |
| 911 | res = ((100.0 - pecent) * (max as f64) / 200.0).round() as usize; |
| 912 | } |
| 913 | } |
| 914 | } |
| 915 | #[cfg(not(windows))] |
| 916 | { |
| 917 | s.refresh_cpu_usage(); |
| 918 | // https://man7.org/linux/man-pages/man3/getloadavg.3.html |
| 919 | let avg = s.load_average(); |
| 920 | info = format!("cpu loadavg: {}", avg.one); |
| 921 | res = (((max as f64) - avg.one) * 0.5).round() as usize; |
| 922 | } |
| 923 | res = std::cmp::min(res, max / 2); |
| 924 | res = std::cmp::min(res, memory as usize / 2); |
| 925 | // Use common thread count |
| 926 | res = match res { |
| 927 | _ if res >= 64 => 64, |
| 928 | _ if res >= 32 => 32, |
| 929 | _ if res >= 16 => 16, |
| 930 | _ if res >= 8 => 8, |
| 931 | _ if res >= 4 => 4, |
| 932 | _ if res >= 2 => 2, |
| 933 | _ => 1, |
| 934 | }; |
| 935 | // https://aomedia.googlesource.com/aom/+/refs/heads/main/av1/av1_cx_iface.c#677 |
| 936 | // https://aomedia.googlesource.com/aom/+/refs/heads/main/aom_util/aom_thread.h#26 |
| 937 | // https://chromium.googlesource.com/webm/libvpx/+/refs/heads/main/vp8/vp8_cx_iface.c#148 |
| 938 | // https://chromium.googlesource.com/webm/libvpx/+/refs/heads/main/vp9/vp9_cx_iface.c#190 |
| 939 | // https://github.com/FFmpeg/FFmpeg/blob/7c16bf0829802534004326c8e65fb6cdbdb634fa/libavcodec/pthread.c#L65 |
| 940 | // https://github.com/FFmpeg/FFmpeg/blob/7c16bf0829802534004326c8e65fb6cdbdb634fa/libavcodec/pthread_internal.h#L26 |
| 941 | // libaom: MAX_NUM_THREADS = 64 |
| 942 | // libvpx: MAX_NUM_THREADS = 64 |
| 943 | // ffmpeg: MAX_AUTO_THREADS = 16 |
| 944 | res = std::cmp::min(res, limit); |
| 945 | // avoid frequent log |
| 946 | let log = match THREAD_LOG_TIME.lock().unwrap().clone() { |
| 947 | Some(instant) => instant.elapsed().as_secs() > 1, |
| 948 | None => true, |
| 949 | }; |
| 950 | if log { |
| 951 | log::info!("cpu num: {max}, {info}, available memory: {memory}G, codec thread: {res}"); |
| 952 | *THREAD_LOG_TIME.lock().unwrap() = Some(Instant::now()); |
| 953 | } |
| 954 | res |