GPU Usage Guide¶
The GPU (Graphics Processing Unit) is a dedicated processor in a device that is primarily responsible for graphics rendering and image processing. If a device is compared to a computer:
The CPU is responsible for “thinking” — processing logic and running programs.
The GPU is responsible for “drawing” — rendering content into images displayed on the screen.
Without a GPU, graphical interfaces, games, videos, and animations cannot be rendered efficiently. GPU performance directly affects the smoothness of graphics processing and the power consumption of the device.
Use Case |
Description |
|---|---|
System UI |
Boot animations, desktop rendering, application switching, drop-down menus, and other UI rendering |
Gaming & Entertainment |
3D games, animation effects, AR applications, and other graphics rendering |
Video Playback |
Video color processing, image enhancement, and HDR effects |
Camera & Photography |
Viewfinder rendering, filter effects, and image enhancement |
General Computing |
Assists the CPU with parallel computing, such as face recognition and AI application acceleration |
GPU Configuration¶
Category |
M1 Description |
L1 Description |
|---|---|---|
Application Processor |
Octa-core 64-bit ARM Kryo™ 260 processor: |
Quad-core 64-bit ARM processor: |
GPU |
64-bit Adreno™ 610 @ 1050 MHz |
64-bit Adreno™ 702 @ 845 MHz |
Display Interface |
1 × Micro HDMI interface, Micro HDMI 2.0 (frame rate*); Encoding: 1080p (H.264/H.265) @ 60 fps*; Decoding: 1080p (H.264/H.265/VP9) @ 60 fps* |
1 × Micro HDMI interface①, HDMI 2.0 (frame rate TBD*); Encoding: 1080p (H.264/H.265) @ 60 fps*; Decoding: 1080p (H.264/H.265/VP9) @ 60 fps* |
GPU Usage¶
Android 4K High-Definition Video Playback¶
Debian OpenCV GPU Acceleration Development and Verification¶
Preparation¶
Development Environment¶
PC: Windows
Development Board: Quectel Pi M1
Operating System: Debian GNU/Linux 13
Development Tools¶
VS Code: Used to write and modify the Benchmark source code.
ADB (Android Debug Bridge): Used to connect to the development board, execute Linux commands, compile programs, and run applications.
Note: Except for source code editing, all Linux commands described in this document, including software installation, environment verification, program compilation, and program execution, are executed in the ADB Shell.
Connect to the Development Board¶
On the PC, open the ADB folder, enter CMD in the address bar to open a command prompt, and run:
adb devices
Confirm that the development board is connected. For example:
List of devices attached
xxxxxxxx device
Enter the development board:
adb shell
Test Purpose¶
Install the official Debian OpenCV 4.10.0 package and verify whether Debian can use the Qualcomm OpenCL Runtime included in the system image to access the Adreno GPU and enable OpenCL GPU acceleration.
Test Environment¶
Item |
Details |
|---|---|
Development Board |
Quectel Pi M1(QSM200U) |
Operating System |
Debian GNU/Linux 13 |
Debian OpenCV |
4.10.0 |
GPU |
Qualcomm Adreno 610 |
OpenCL Runtime |
Qualcomm OpenCL Runtime |
Install OpenCV from the Official Debian Repository¶
apt update
apt install g++ pkg-config libopencv-dev python3-opencv
Verify the installation after it is complete:
opencv_version
pkg-config --modversion opencv4
dpkg -l | grep opencv
Verification results:
opencv_version: 4.10.0
pkg-config: 4.10.0
dpkg: Debian OpenCV 4.10.0
Verify the OpenCL Runtime¶
Check the OpenCL libraries available in the system:
find /usr/lib -name "libOpenCL*"
Confirm that the following libraries are present:
libOpenCL.so
libOpenCL.so.1
libOpenCL.so.1.2
libOpenCL_adreno.so
Write the Benchmark Program¶
Create the opencv_gpu_benchmark.cpp file in VS Code.
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <iostream>
#include <string>
static double run_cpu(const cv::Mat &src, int loops, cv::Mat &result)
{
cv::ocl::setUseOpenCL(false);
cv::Mat current = src.clone();
cv::Mat next;
for (int i = 0; i < 5; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
current = src.clone();
const int64 start = cv::getTickCount();
for (int i = 0; i < loops; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
const int64 end = cv::getTickCount();
result = current.clone();
return (end - start) * 1000.0 / cv::getTickFrequency();
}
static double run_gpu(const cv::Mat &src, int loops, cv::Mat &result)
{
cv::ocl::setUseOpenCL(true);
if (!cv::ocl::useOpenCL()) {
std::cerr << "OpenCL could not be enabled." << std::endl;
return -1.0;
}
cv::UMat current;
cv::UMat next;
src.copyTo(current);
for (int i = 0; i < 5; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
src.copyTo(current);
cv::ocl::finish();
const int64 start = cv::getTickCount();
for (int i = 0; i < loops; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
cv::ocl::finish();
const int64 end = cv::getTickCount();
current.copyTo(result);
return (end - start) * 1000.0 / cv::getTickFrequency();
}
int main(int argc, char **argv)
{
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " cpu|gpu|both" << std::endl;
return 1;
}
const std::string mode = argv[1];
const int loops = 500;
cv::Mat src(2160, 3840, CV_32FC1);
cv::randu(src, 0.0f, 1.0f);
std::cout << "OpenCV version: " << CV_VERSION << std::endl;
std::cout << "haveOpenCL: " << cv::ocl::haveOpenCL() << std::endl;
std::cout << "Image size: 3840x2160, CV_32FC1" << std::endl;
std::cout << "Loops: " << loops << std::endl;
if (mode == "cpu") {
cv::Mat cpu_result;
const double cpu_ms = run_cpu(src, loops, cpu_result);
std::cout << "Mode: CPU" << std::endl;
std::cout << "CPU total time: " << cpu_ms << " ms" << std::endl;
std::cout << "CPU average time: "
<< cpu_ms / loops << " ms" << std::endl;
}
else if (mode == "gpu") {
cv::ocl::Context context;
if (!context.create(cv::ocl::Device::TYPE_GPU)) {
std::cerr << "Failed to create GPU context." << std::endl;
return 1;
}
cv::ocl::Device device = context.device(0);
std::cout << "Mode: GPU" << std::endl;
std::cout << "Device name: " << device.name() << std::endl;
std::cout << "Vendor: " << device.vendorName() << std::endl;
std::cout << "OpenCL version: " << device.version() << std::endl;
cv::Mat gpu_result;
const double gpu_ms = run_gpu(src, loops, gpu_result);
if (gpu_ms < 0.0) {
return 1;
}
std::cout << "GPU total time: " << gpu_ms << " ms" << std::endl;
std::cout << "GPU average time: "
<< gpu_ms / loops << " ms" << std::endl;
}
else if (mode == "both") {
cv::Mat cpu_result;
cv::Mat gpu_result;
const double cpu_ms = run_cpu(src, loops, cpu_result);
const double gpu_ms = run_gpu(src, loops, gpu_result);
if (gpu_ms < 0.0) {
return 1;
}
const double max_difference =
cv::norm(cpu_result, gpu_result, cv::NORM_INF);
std::cout << "Mode: BOTH" << std::endl;
std::cout << "CPU average time: "
<< cpu_ms / loops << " ms" << std::endl;
std::cout << "GPU average time: "
<< gpu_ms / loops << " ms" << std::endl;
std::cout << "Speedup: "
<< cpu_ms / gpu_ms << "x" << std::endl;
std::cout << "Maximum result difference: "
<< max_difference << std::endl;
if (max_difference < 0.01) {
std::cout << "Result check: PASS" << std::endl;
} else {
std::cout << "Result check: FAIL" << std::endl;
return 1;
}
}
else {
std::cerr << "Invalid mode. Use cpu, gpu or both." << std::endl;
return 1;
}
return 0;
}
The program mainly performs the following functions:
Creates a test image
Executes cv::multiply() on the CPU
Executes cv::multiply() on the GPU using UMat
Measures the average execution time of the CPU and GPU separately
Verifies that the CPU and GPU calculation results are consistent
Outputs the GPU acceleration ratio (Speedup)
Compile the Benchmark¶
Save the opencv_gpu_benchmark.cpp file created in VS Code to the ADB folder on the PC, and then push it to the development board:
adb push opencv_gpu_benchmark.cpp /data/local/tmp/
Enter the source directory:
cd /data/local/tmp
Compile:
g++ -O2 opencv_gpu_benchmark.cpp -o opencv_gpu_benchmark $(pkg-config --cflags --libs opencv4)
The executable file is generated:
opencv_gpu_benchmark
Run the Benchmark¶
export LD_LIBRARY_PATH=/opt/qcom/lib:$LD_LIBRARY_PATH
./opencv_gpu_benchmark both
Running result:
OpenCV version: 4.10.0
haveOpenCL: 1
CPU average time: 28.9083 ms
GPU average time: 0.0474746 ms
Speedup: 608.92x
Maximum result difference: 0.000506639
Result check: PASS
Test Notes¶
In this test, the official Debian OpenCV GPU Benchmark achieved a GPU speedup of approximately 608.92×.
It should be noted that the test program uses only the OpenCV cv::multiply() operator for performance verification. This is a basic OpenCL functionality test with a relatively small computational workload. As a result, the GPU execution time is close to the timing precision of the benchmark, which causes the calculated speedup ratio to be significantly higher than expected.
Therefore, the Benchmark result is mainly used to verify that OpenCV can successfully invoke the GPU for OpenCL computation. The 608.92× result should not be regarded as an overall GPU performance metric.
Frequently Asked Questions¶
Device UI Lag or Frame Drops?¶
Check whether too many applications are running in the background and close unnecessary programs.
If the device is overheating, allow it to cool down. The operating frequency will automatically recover after the temperature decreases.
Screen Artifacts or Display Abnormalities?¶
Check whether the HDMI cable and display connections are secure.
Confirm that the screen or monitor resolution and refresh rate are configured correctly.
Try another cable or display to rule out hardware issues.
If a new LCD screen is being used, make sure its specifications and resolution are compatible with the device.
Large Games or 3D Applications Crash?¶
The device GPU is entry-level, and extremely demanding applications may exceed its performance capabilities.
Try lowering the graphics quality or resolution settings.
Ensure proper heat dissipation and avoid covering or blocking the device.
GPU Overheating or High Power Consumption?¶
Heat generation under high GPU load is normal. The system automatically reduces the operating frequency when necessary to provide thermal protection.
Check whether any applications are continuously using the GPU, such as background video playback or animations.