1 #include<opencv2/opencv.hpp> 2 usando el espacio de nombres cv; 3 #include <numérico> // std::iota 4 5 const int g_num = 1000; 6 7 void my_test1(double* p_arr) 8 { 9 for (size_t i = 0; i < g_num; i++) 10 { 11 int p_arr_i = p_arr[i]; 12 for (size_t j = 0; j < g_num; j++) 13 { 14 double num1 = p_arr_i * (j > 10 ? 10 : j); 15 doble número2 = std::pow(num1, 2); 16 doble número3 = std::sqrt(num2); 17 p_arr[i] = número3; 18 p_arr[i] = p_arr_i * núm3; 19 p_arr[i] = p_arr[i] / num3; 20 } 21 } 22 } 23 24 void my_test2(double* p_arr) 25 { 26 27 paralelo_for_(Rango(0, g_num), [&](const Rango& r) 28 { 29 for (int oc = r.start; oc < r.end; oc++) 30 { 31 // Similar a la función del kernel parte 32 int p_arr_i = p_arr[oc]; 33 for (size_t j = 0; j < g_num; j++) 34 { 35 double num1 = p_arr_i * (j > 10 ? 10 : j); 36 doble num2 = std::pow(num1, 2); 37 doble num3 = std::sqrt(num2); 38 p_arr[oc] = num3; 39 p_arr[oc] = p_arr_i * num3; 40 p_arr[oc] = p_arr[oc] / num3; 41 } 42 } 43 }); 44 } 45 46 int main() 47 { 48 números dobles[g_num]; 49 puntos enteros = 0; 50 std::iota(números, números + g_num, st); // 100 101 102 103 51 52 53 54 55 doble t = (doble)getTickCount(); 56 my_test1(números); 57 t = (doble)getTickCount() - t; 58 59 doble t2 = (doble)getTickCount(); 60 my_test2(números); 61 t2 = (doble)getTickCount() - t2; 62 63 printf("conv3x3 tiempo = %.1fms\n", t * 1000 / getTickFrequency()); 64 printf("conv3x3_parallel time = %.1fms\n", t2 * 1000 / getTickFrequency()); 65 66 67 68 sistema("pausa"); 69 devuelve 0; 70 }
La tarea debe ser lo suficientemente compleja como para tener un efecto de aceleración. Por ejemplo, una tarea simple como +1 para cada píxel no es tan rápida como un solo hilo en un bucle for.
Es simple de usar, no es más que escribir la parte de "función kernel" adecuada para el paralelismo en la posición apropiada, por ejemplo:
paralelo_for_(Range(0, g_num), [&](const Range& r) { for (int oc = r.start; oc < r.end; oc++) { // Similar a la parte de la función del núcleo int p_arr_i = p_arr[oc ] ; for (size_t j = 0; j < g_num; j++) { double num1 = p_arr_i * (j > 10 ? 10 : j); double num2 = std::pow(num1, 2); double num3 = std:: sqrt (num2); p_arr[oc] = num3; p_arr[oc] = p_arr_i * num3; p_arr[oc] = p_arr[oc] / num3; } } });
Wen Xin respondió en una palabra.
opencv multiproceso
Sí, OpenCV proporciona una API para subprocesos múltiples. A partir de la versión 4.5 de OpenCV, introduce soporte para algoritmos paralelos estándar de C++ 11. Esto significa que puede utilizar subprocesos múltiples para acelerar su código OpenCV.
En OpenCV, puedes usar parallel::ThreadPool
clases para crear y administrar grupos de subprocesos. Esta clase proporciona una forma sencilla de asignar tareas y ejecutarlas en paralelo en un grupo de subprocesos.
Aquí hay un código de ejemplo simple que demuestra cómo usar el grupo de subprocesos de OpenCV:
cppCopiar código
1 #incluir <opencv2/opencv.hpp> 2 #incluir <opencv2/core.hpp> 3 #incluir <opencv2/highgui.hpp> 4 #incluir <opencv2/imgproc.hpp> 5 #incluir <opencv2/parallel/thread_pool. hpp> 6 7 usando el espacio de nombres cv; 8 usando el espacio de nombres cv::parallel; 9 10 int main() 11 { 12 // Crear un grupo de subprocesos que contenga 4 subprocesos 13 ThreadPool pool(4); 14 15 // Cargar imagen 16 Imagen de tapete = imread("ejemplo.jpg"); 17 18 if (image.empty()) { 19 std::cerr << "No se pudo cargar el archivo de imagen." << std::endl; 20 return -1; veintiuno } 22 23 // Pasa la imagen a la tarea en el grupo de subprocesos para su procesamiento paralelo 24 pool.enqueueJob([&](int) { 25 // Procesa la imagen aquí, como la conversión en escala de grises 26 cvtColor(image, image, COLOR_BGR2GRAY); 27 }); 28 29 // Espera a que se completen todas las tareas 30 pool.waitAll(); 31 32 // Muestra la imagen procesada 33 imshow("Imagen procesada", imagen); 34 waitKey(0); 35 36 return 0; 37 }
En el ejemplo anterior, creamos un grupo de subprocesos con 4 subprocesos y pasamos las imágenes a tareas en el grupo de subprocesos para su procesamiento en paralelo. Cada tarea realiza una operación de conversión a escala de grises en la imagen. Luego esperamos a que se completen todas las tareas y muestre la imagen procesada.
Cabe señalar que el procesamiento de subprocesos múltiples puede introducir cierta sobrecarga adicional, incluida la creación y administración de subprocesos, la sincronización de datos, etc. Por lo tanto, antes de utilizar subprocesos múltiples, debe evaluar cuidadosamente los escenarios de su aplicación y el rendimiento del código, y realizar ajustes y optimizaciones en función de la situación real.