Use intel vtune to find hotspot program optimization code

Source: Internet
Author: User

Or the hard-pressed Web Search job last time. If it was done, forget it. I ran the program to vtune and found several hot programs. It seems that there is always a little bit of sorrow in my mind. So we went on the road of optimization. In fact, this road is easy to complete. In particular, cainiao like me have used up all the optimization tricks and this road has come to an end. I'm not going to take advantage of my talent. Let's just focus on it.

Background: My main task is to build a document vector. For the definition of Vector in this document, see my previous blog. What I use most is to count the number of words that appear in a word, and there is also a word that appears in several documents. I used the STD: Map <string, int> data structure to help me find the number of words that appear in a word. My optimization started with the use of STD: map...

The vtune version I used is vtune amplifier Xe 2011. The programming environment is fedora 15. The selected type is hot function. Click Start to analyze the hotspot program. There are few documents to be counted during the first running. The running time is 0.24 S, and the first hotspot function obtained is accfreqidf. This function is used to count how many times a word appears and how many documents a word appears. Double-click the function name button to open the corresponding source file. The first line of the Code is a bottleneck:

1 if( !m_IDF[keyword].showup ) //hot function detected by vtune
2 {
3 m_IDF[keyword].num++;
4 m_IDF[keyword].showup = true;
5 }

For a keyword that appears in several documents, I first thought about this method: defining a struct, including int num and bool showup; in the initial state, showup is false. If a keyword appears in a document, its showup is true. Since then, no matter how many times the keyword num appears, it will not increase. The IF statement can ensure that as long as a keyword appears in a document, the count is increased by 1, regardless of the number of times it appears. However, this judgment statement is used too frequently and becomes a hotfunction. The following code is available:

 1 map<string,int> tmpIDF;
2 tmpIDF.clear();
3
4 while(!file.eof())
5 {
6 //read in every words
7 file >> keyword;
8 //tmpIDF.clear();
9 tmpIDF[keyword] = 1;//set keyword to 1
10 //----------------------------
11 //acc idf
12 //if( !m_IDF[keyword].showup ) //hot function detected by vtune
13 //{
14 // m_IDF[keyword].num++;
15 //m_IDF[keyword].showup = true;
16 //}
17 timePerWord[keyword]++;
18
19 }//end while
20 //insert showup keywords to m_IDF map
21 map<string,int>::iterator iterTmpIdf = tmpIDF.begin();
22 for( ; iterTmpIdf != tmpIDF.end(); iterTmpIdf++)
23 {
24 //cout << iterTmpIdf->first << endl;
25 m_IDF[iterTmpIdf->first].num++;
26 }
27 }

In each file, I define a STD: Map <string, int> tmpidf. As shown in row 9th, all the keywords in this document are inserted into tmpidf. Tmpidf only stores the keywords that appear in the file, regardless of the number of times each keyword appears. After counting the current file, merge tmpidf into the large map m_idf. See rows 21st to 26. I use the map m_idf to store each keyword of all documents in several documents. This avoids the use of IF Statements. Then sent to vtune for analysis, and the efficiency was significantly improved. The running time is reduced from 0.12 s to S.

You may say that the running time is too short. What if the number of documents increases? When I increased the number of documents, I found that the running time was 2.4 s, which had a new bottleneck. The hotspot function becomes the 4th line of the following code in the calctfidf function:

 1 for(map<string,NumIDF>::iterator idfIt = m_IDF.begin(); idfIt!=m_IDF.end();        ++idfIt)
2 {
3 //for every keywords
4 int freqij = elem[idfIt->first];
5 int maxj = iter->second;
6 int N = m_MaxFreq.size();
7 float ni = (float)idfIt->second.num;
8 float tmp = (freqij/(float)maxj)*log((float)N/ni);
9 rkdv.push_back(tmp);
10 }

The function of this Code is to build a document vector. Let's take an example to illustrate the document vector:
Now there are three documents, a.txt B .txt and c.txt. The keyword in a.txt is happy. In B .txt, the keyword is merry. c.txt, And the keyword is New Year. Each keyword appears once. All the following vectors can be constructed:
Happy Merry New Year
A.txt 1 0 0 0
B .txt 0 1 0 0
C.txt 0 0 1 1 1

The obtained document vectors are a.txt (,) B .txt (,) c.txt ). Of course, this is just an example. The real computation needs to be more complex, such as the Code of the above 8th lines.
In the old method, I stored the keywords in each document in the ELEM variable. M_idf stores all the keywords of all documents. I used ELEM [idfit-> first] to query all the keywords in the document. For example. A.txt map is saved as follows: (happy, 1) (Happy appears once ). However, after executing ELEM ["Merry"]; ELEM ["new"]; ELEM ["year"], you can get the correct result, but Operator Functions are inserted, so a.txt stores a map like this: (happy, 1) (Merry, 0) (new, 0) (year, 0 ). there are many unnecessary operations. Therefore, this function is very time-consuming. So I adopted the following improvement methods:

 1 map<string,NumIDF>::iterator iter = m_IDF.begin();
2 int index = 0;
3 for(; iter != m_IDF.end(); iter++)
4 {
5 iter->second.showup = index++;
6 }
7 .....
8 ......
9
10 for( ; elemIter != elem.end(); elemIter++)
11 {
12 //get index in vector
13 const NumIDF& nidf = m_IDF[elemIter->first];
14 int indVec = nidf.showup;
15 //get the pointer to write to
16 advance(dvIter,indVec - lastInd);
17 lastInd = indVec;
18 int freqij = elemIter->second;
19 int maxj = iter->second;
20 int N = m_MaxFreq.size();
21 float ni = (float)nidf.num;
22 float tmp = (freqij/(float)maxj)*log((float)N/ni);
23 *dvIter = tmp;
24 }

The document vector is stored by vector <float>. However, many values of this vector are 0, because no keywords appear in this document. First, I traverse the map m_idf and show each keyword in several documents and the keyword in the struct where m_idf is the first and has a numidf tutorial. For each document, I only traverse the keywords that appear in the document. Find the number of this keyword in m_idf. Therefore, the elements of the vector <float> are set to non-0 values. Set the value of vector <float> to 0 at other locations. In this way, the running time of the program is reduced from 2.5s to 0.5 s. I was so happy that I had a morning and planned to hand in my homework. It was not optimized...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.