Quick check for a equal value in a integer vector

Mar 3, 2016 at 10:58pm
Hi my friends,
i want to ask , if somebody know some instruction for make next code quicker :
1
2
3
4
5
bool haveFree(const vector<int> &F)
{
    for(int x : F) { if (x<0) return true;}
    return false;
}

Thanks for any help.
Daniel
Mar 4, 2016 at 2:48pm
No, I think this is about as optimized as it can get!
Is there any particular reason you need it this fast?
Last edited on Mar 4, 2016 at 2:49pm
Mar 4, 2016 at 11:00pm
Hi, thanks for your answer.
May be exist a assembler instruction to check iteratively in same range, and would be quicker (MMX?), but this may be would be mission of C++ to implement it for a standard library ("if_any") and for specialization for integer.
Reason is this because, a call from a kernel of a algorithm is to this function, and it is often. The algorithm' mission is to calculate a "minimal combination's of pih's", and this is part of a algorithm to found optimal algorithms for order elements by comparison. :)
I already try to minimize a call to this function, maintaining another array, which count how many place of F are less as 0.
greatings, Daniel
Mar 4, 2016 at 11:28pm
nolyc wrote:
You're trying to do X, and you thought of solution Y. So you're asking about solution Y, without even mentioning X. The problem is, there might be a better solution, but we can't know that unless you describe what X is.
Mar 5, 2016 at 3:39am
Even now it is not evident that solution Z is better as solution Y.
All depend of Y have a fast way or not, using processors capabilities.
If Y have a faster way, then Y would be better as Z, so i ask about this.
Even using solution Z is not vey much better as use solution without quick way.
Anyway i can give a code, from calling function. Explain everything would be very long.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
int foundMinPihcInLine(int minPihc,int validLineI,int nextPihcsB)
{
    int lineI = m_validLines[validLineI];
    int lastP = m_lines[lineI];//point to last pihs,last pointers from this line
    if (haveFree(F)) {
        //so we can simply choice a minimal of F(x)
        int minLPih = pasa;
        int minLPihc = pasa;
        int minLPihPlace = 0;
        int size = m_freePihss[lineI].size();//freePihs.size();
        for(int t=0;t<size;t++) {
            int pih = m_freePihss[lineI][t];//freePihs[t];
            int pihc = convertPihToPihc(pih,m_Fs[lineI]);
            if (pihc<minLPihc) { minLPihc=pihc; minLPih=pih; minLPihPlace=t;}
        }
        if (minLPihc<minPihc) {
            minPihc = minLPihc;
            m_newValidLines.clear();
        }
        if (minLPihc<=minPihc) { //simply continue line
            m_pihs.push_back(minLPih);//data place 1
            m_pointers.push_back(lastP);//it is continuation from previous
            ivec newF(m_Fs[lineI]);//ivec newF(F);
            vector<int> newFreePihs(m_freePihss[lineI]);
            newFreePihs[minLPihPlace] = m_freePihss[lineI].back();//freePihs.back();
            newFreePihs.resize(size-1);
            m_lines.push_back(m_pihs.size()-1);//line data 1
            m_Fs.push_back(newF);//line data 2
            m_freePihss.push_back(newFreePihs);//line data 3
        }
        return minPihc;
    }
    //we collect all pih's which result in a minimal pihc (minPihc)
    ivec minPihs;
    ivec pihPlaces;//places inside freePihs
    int size = m_freePihss[lineI].size();//freePihs.size();
    for(int t=0;t<size;t++) {
        int pih = m_freePihss[lineI][t];//freePihs[t];
        int minPihcPih = foundMinPihcForPih(pih,m_Fs[lineI],lineI);//similar to foundMinRec2
        if (minPihcPih==minPihc) {
            minPihs.push_back(pih);
            pihPlaces.push_back(t);
        }
        else if (minPihcPih<minPihc) {
            minPihs.clear();
            minPihs.push_back(pih);
            minPihc = minPihcPih;
            pihPlaces.clear();
            pihPlaces.push_back(t);
            m_newValidLines.clear();//we invalidate all previous lines, which give a smaller pihc
        }
    }
    int xc = pairsP[minPihc].first;
    int yc = pairsP[minPihc].second;
    int lastFreePih = m_freePihss[lineI].back();//freePihs.back();
    //save all optimal results :
    for(int t=0;t<minPihs.size();t++) {
        int pih = minPihs[t];
        int line = m_lines.size();
        m_newValidLines.push_back(line);
        int pointTo = m_pihs.size();
        m_pihs.push_back(pih);//data place 1
        m_pointers.push_back(lastP);//data place 2
        ivec newF(m_Fs[lineI]);//ivec newF(F);
        newF[pairsP[pih].first] = xc;
        newF[pairsP[pih].second] = yc;
        //vector<int> newFreePihs(freePihs);
        vector<int> newFreePihs(m_freePihss[lineI]);
        newFreePihs[pihPlaces[t]] = lastFreePih;
        newFreePihs.resize(size-1);
        m_lines.push_back(pointTo);//line data 1
        m_Fs.push_back(newF);//line data 2
        m_freePihss.push_back(newFreePihs);//line data 3
    }
    return minPihc;
}


Anyway thanks for your try.
Daniel
Mar 5, 2016 at 4:13am
You aren't going to find a magic solution to doing an O(n) search any faster.

If you want to improve the speed, use a std::unordered_set to check for membership, and the std::vector for the sequence ordering. Notice the trade-off: use more memory for a faster membership predicate.
Mar 5, 2016 at 5:15am
A std::unordered_set is quick for check something, but use more memory and also, if i need to copy a unordered_set, its more slowly. Sometimes i need to copy everything.
So, at this moment my solution for this is use another array of counters, which count how many places of F are below of 0. Actually code look like :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
int foundMinPihcInLine(int minPihc,int validLineI,int nextPihcsB)
{
    int lineI = m_validLines[validLineI];
    int lastP = m_lines[lineI];//point to last pihs,last pointers from this line
    if (m_FsFreeN[lineI]==0) {
        //so we can simply choice a minimal of F(x)
        int minLPih = pasa;
        int minLPihc = pasa;
        int minLPihPlace = 0;
        int size = m_freePihss[lineI].size();//freePihs.size();
        for(int t=0;t<size;t++) {
            int pih = m_freePihss[lineI][t];//freePihs[t];
            int pihc = convertPihToPihc(pih,m_Fs[lineI]);
            if (pihc<minLPihc) { minLPihc=pihc; minLPih=pih; minLPihPlace=t;}
        }
        if (minLPihc<minPihc) {
            minPihc = minLPihc;
            m_newValidLines.clear();
        }
        if (minLPihc<=minPihc) { //simply continue line
            m_pihs.push_back(minLPih);//data place 1
            m_pointers.push_back(lastP);//it is continuation from previous
            ivec newF(m_Fs[lineI]);//ivec newF(F);
            vector<int> newFreePihs(m_freePihss[lineI]);
            newFreePihs[minLPihPlace] = m_freePihss[lineI].back();//freePihs.back();
            newFreePihs.resize(size-1);
            m_lines.push_back(m_pihs.size()-1);//line data 1
            m_Fs.push_back(newF);//line data 2
            m_FsFreeN.push_back(0);
            m_freePihss.push_back(newFreePihs);//line data 3
        }
        return minPihc;
    }
    //we collect all pih's which result in a minimal pihc (minPihc)
    ivec minPihs;
    ivec pihPlaces;//places inside freePihs
    int size = m_freePihss[lineI].size();//freePihs.size();
    for(int t=0;t<size;t++) {
        int pih = m_freePihss[lineI][t];//freePihs[t];
        int minPihcPih = foundMinPihcForPih(pih,m_Fs[lineI],lineI);//similar to foundMinRec2
        if (minPihcPih==minPihc) {
            minPihs.push_back(pih);
            pihPlaces.push_back(t);
        }
        else if (minPihcPih<minPihc) {
            minPihs.clear();
            minPihs.push_back(pih);
            minPihc = minPihcPih;
            pihPlaces.clear();
            pihPlaces.push_back(t);
            m_newValidLines.clear();//we invalidate all previous lines, which give a smaller pihc
        }
    }
    int xc = pairsP[minPihc].first;
    int yc = pairsP[minPihc].second;
    int lastFreePih = m_freePihss[lineI].back();//freePihs.back();
    //save all optimal results :
    for(int t=0;t<minPihs.size();t++) {
        int pih = minPihs[t];
        int line = m_lines.size();
        m_newValidLines.push_back(line);
        int pointTo = m_pihs.size();
        m_pihs.push_back(pih);//data place 1
        m_pointers.push_back(lastP);//data place 2
        ivec newF(m_Fs[lineI]);//ivec newF(F);
        newF[pairsP[pih].first] = xc;
        newF[pairsP[pih].second] = yc;
        vector<int> newFreePihs(m_freePihss[lineI]);
        newFreePihs[pihPlaces[t]] = lastFreePih;
        newFreePihs.resize(size-1);
        m_lines.push_back(pointTo);//line data 1
        m_Fs.push_back(newF);//line data 2
        int FsFreeN = m_FsFreeN[lineI];
        if (m_Fs[lineI][pairsP[pih].first]<0) FsFreeN--;
        if (m_Fs[lineI][pairsP[pih].second]<0) FsFreeN--;
        m_FsFreeN.push_back(FsFreeN);
        m_freePihss.push_back(newFreePihs);//line data 3
    }
    return minPihc;
}


Thanks also for you idea Duoas.
Daniel
Last edited on Mar 5, 2016 at 5:16am
Mar 5, 2016 at 7:47am
I found some information about MMX,SIMD and similar instructions together with C++ :
One, is try to use a activation of a flag of compiler gcc with -03.
Information i found at :
https://gcc.gnu.org/projects/tree-ssa/vectorization.html
Below are examples in which gcc will be able to use vectorization.
Also : -O3 -mfpmath=sse
At
https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/i386-and-x86_002d64-Options.html
are compiler options.
A example at : http://tommesani.com/index.php/component/content/article/2-simd/42-mmx-examples.html
A real example using assembler with C++ :
http://www.codeproject.com/Articles/38519/Using-Assembler-and-SSE-SSE-instructions-for-dra
Another : http://www.codeproject.com/Articles/4662/High-performance-computing-from-C-to-MMX
Also exist a C++ interface for use MMX
More :
http://www.codeproject.com/Articles/4662/High-performance-computing-from-C-to-MMX
http://www.codeproject.com/Articles/12115/STL-like-template-based-coding-with-the-MMX-SSE-ex

I send this in case somebody have interest in it.

greating, Daniel
Mar 6, 2016 at 6:38am
I have a question in mind. Since the int is 4 byte, By using reference in for loop, Is it make the code quicker or not?
for(int& x: f) ...
Is using reference make code faster in bigger data type or it is just memory saver?
Mar 6, 2016 at 10:16am
According to Bjarne Stroustrup we should prefer the stl algorithms over loops. In this case probably find_if would be a better option.
Mar 6, 2016 at 4:10pm
Thanks, it is also a idea.
But may be a good compiler already will compile like this, i dont know.
greatings, Daniel
Topic archived. No new replies allowed.