当前位置:网站首页>Efficiency difference between row first and column first traversal of mat data types in opencv
Efficiency difference between row first and column first traversal of mat data types in opencv
2022-07-05 21:35:00 【MrL_ JJ】
List of articles
One 、 How arrays are stored in memory
Array is the basis of data structure , The reason for this is that arrays reflect the physical structure of memory . In memory , Arrays are continuously distributed . And in the program , It is often necessary to allocate a continuous piece of space in memory to use . for example , In the neighborhood of image processing , Familiar with opencv There is a data type in Mat, We usually use Mat To store image data .Mat Is a two-dimensional array , Two for Loop through the values of each pixel on the image . Some people are used to traversing by line first , Some people like to traverse by column first , On the surface , The time complexity of these two methods is O(nm)(n Indicates the height of the image ,m Represents the width of the image ), But are they all O(nm) Well ?
Two 、 Code examples and results
The code of column first traversal is as follows ( Example ):
Mat src = imread("image0.jpg", IMREAD_GRAYSCALE);
if (!src.empty())
imshow("src", src);
int nums = 10;
while (nums)
{
double t = (double)getTickCount();
for (int i = 0; i < src.cols; i++)
{
for (int j = 0; j < src.rows; j++)
{
uchar srcValue = src.at<uchar>(j, i);
}
}
t = ((double)getTickCount() - t) / getTickFrequency(); // For the time , The unit is seconds
cout << "time:" << t<<"ms"<<endl;
nums--;
}
Through a cycle , Repeat the test 10 Time , The time-consuming of column priority traversal is printed through the console as follows :
Line first traversal code is as follows ( Example ):
Mat src = imread("image0.jpg", IMREAD_GRAYSCALE);
if (!src.empty())
imshow("src", src);
int nums = 10;
while (nums)
{
double t = (double)getTickCount();
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
uchar srcValue = src.at<uchar>(i, j);
}
}
t = ((double)getTickCount() - t) / getTickFrequency(); // For the time , The unit is seconds
cout << "time:" << t<<"ms"<<endl;
nums--;
}
Again , Row first traversal also passes through a loop , Repeat the test 10 Time , The time consumption is printed as follows through the console :
Through the above tests, we can find that , Row first traversal is faster than column first .
3、 ... and . analysis
1. CPU Cache ( English :CPU Cache): In computer system ,CPU Cache is a component used to reduce the average time required by the processor to access memory . When the processor makes a memory access request , It will first check whether there is request data in the cache . If there is ( hit ), Return the data directly without access to memory ; If it doesn't exist ( invalid ), First, load the corresponding data in memory into the cache , Return it to the processor . Why caching works , The main reason is that the access to memory when the program is running is local (Locality) features . This locality includes both spatial locality (Spatial Locality), It also includes time locality (Temporal Locality). Use this locality effectively , Cache can achieve a very high hit rate .( Baidu Encyclopedia explains ).
2. Virtual memory : Virtual memory is used by the operating system to manage memory , Expand physical memory , Its function is to replace part of the work of physical memory to run programs , Let the operating system run more programs , Perform more tasks at the same time .
3. The storage structure of two-dimensional array in memory is shown in the figure below : Data is stored in memory in a row first manner .

4. The image size of the code test is 4096X1200, Bit depth is 8, Here's the picture . The reason why row first traversal is faster than column first , Because cpu When accessing the memory address , The first thing to access is virtual memory , Check TLB, Map to the corresponding physical address for data access . If hit , Will get its physical address , After that, I will visit cache, If cache There is data to access in , Then this visit is over , without , Just look in memory , And update the cache; If TLB Miss hit , Then the system kernel will call the missing page exception handler to handle , Page replacement and other operations will be carried out in this process , Finally get the data to be accessed . In the physical address of memory , Two dimensional arrays are stored in row first order , The size of the test image data is 4096X1200 byte , Suppose the memory page is 4096 byte , Then traverse by line first , After traversing a line, the page is broken once , The whole process only needs to be interrupted 1200 Next page missing exception , Make page replacement . And traverse by column first , Every time you traverse an element, you break the page missing exception , The whole process 4096X1200 Interrupt times , As one can imagine , The interruption time of traversal by column first is much larger than that of traversal by row first . In reality, physical memory is generally sufficient , The system allocates far more page memory 4096 byte , So there won't be so many page breaks . Empathy , If you check TLB hit , After getting its physical address, you will visit cache, If cache There is no data to access , Just look in memory , And update the cache; Due to the storage mode of two-dimensional array in memory , Traverse the access by column first cache The hit rate of is lower than that of traversing by row first .
in summary : Row first traversal is faster than column first .
边栏推荐
- PVC plastic sheets BS 476-6 determination of flame propagation properties
- Incentive mechanism of Ethereum eth
- Reading and writing operations of easyexcel
- leetcode:1755. Sum of subsequences closest to the target value
- Explain various hot issues of Technology (SLB, redis, mysql, Kafka, Clickhouse) in detail from the architecture
- PostGIS installation geographic information extension
- 第05章_存储引擎
- one hundred and twenty-three thousand four hundred and fifty-six
- vant 源码解析 event.ts 事件处理 全局函数 addEventListener详解
- sql常用语法记录
猜你喜欢

Some common processing problems of structural equation model Amos software

leetcode:1755. Sum of subsequences closest to the target value

Golang (1) | from environmental preparation to quick start

EN 438-7 laminated sheet products for building covering decoration - CE certification

Teach yourself to train pytorch model to Caffe (I)

Cold violence -- another perspective of objective function setting

張麗俊:穿透不確定性要靠四個“不變”

冯唐“春风十里不如你”数字藏品,7月8日登录希壤!

Li Kou ----- the maximum profit of operating Ferris wheel

Access Zadig self-test environment outside the cluster based on ingress controller (best practice)
随机推荐
Aitm2-0002 12s or 60s vertical combustion test
int GetMonth( ) const throw( ); What does throw () mean?
2022-07-03-CKA-粉丝反馈最新情况
Learning robots have no way to start? Let me show you the current hot research directions of robots
"Grain mall" -- Summary and induction
SQL knowledge leak detection
100 cases of shell programming
Reading and writing operations of easyexcel
Teach yourself to train pytorch model to Caffe (I)
Parker driver maintenance COMPAX controller maintenance cpx0200h
selenium 获取dom内属性值的方法
Cross end solution to improve development efficiency rapidly
Deep merge object deep copy of vant source code parsing
GCC9.5离线安装
Some common processing problems of structural equation model Amos software
vant 源码解析之 utils/index.ts 工具函数
Get JS of the previous day (timestamp conversion)
How to send samples when applying for BS 476-7 display? Is it the same as the display??
Zhang Lijun: la pénétration de l’incertitude dépend de quatre « invariants»
Using webassembly to operate excel on the browser side