[SSE] Zahl von Vektor abziehen



  • Hallo,

    ich hab hier eine Funktion, die von einem Vektor eine Zahl abziehen soll. Da der Vektor ziemlich lange ist, benütze ich dafür SSE.

    Also, die Funktion sieht folgendermaßen aus:

    SSE_Subtract(std::vector<int,alignment_allocator<int,16> >& vector,int subtract_value, size_t begin_index, size_t end_index)
    

    vector ist natürlich der Vektor, subtract_value die Zahl die abgezogen werden soll.
    begin_index ist der Index der ersten Zahl, end_index der Index der letzten Zahl von der subtract_Value abgezogen werden soll.

    Wenn ich nun jetzt diesen Vektor habe:

    0, 1, 2, 3, 4, 5, 6, 7, 8
    

    dann sollte

    SSE_Subtract(vector, 2, 4, 7)
    

    folgendes auswerfen:

    0, 1, 2, 3, 2, 3, 4, 5, 8
    

    Bei SSE müssen ja die Zahlen auf einer Adresse liegen, die durch 16 teilbar ist. Also kann ich hier nur Zahlen hernehmen, die auf einem Index liegen für den gilt: Index % 4 == 0
    Und gleichzeitig muss ich bei einem Index dann aufhören, für den wieder das gleiche gilt, ansonsten überschreibe ich ja die Daten dahinter.

    So sieht meine Fnktion jetzt aus:
    (Hinweis a % 4 == a & 3)

    //SSE function
    #if OSG_USE_SSE
    	void CNumberSeriesCache::SSE_Subtract(std::vector<int,alignment_allocator<int,16> >& vector,int subtract_value, size_t begin_index, size_t end_index)
    	{
    		/*
    		complicated, ugly and can only be understand by pros :D
    		don't change this because optimization is the root of all evil
    		(and Bush will bomb your house!)
    		*/
    
    		size_t size = end_index - begin_index;
    		size_t sse_begin_index;
    		size_t sse_end_index; 
    		//size_t sse_vector_size = vector_size - vector_size%4; //the number of elements, that can be used in sse
    		//optimization (does the same as the code above):
    		//size_t sse_vector_size = vector_size - (vector_size & 3); //remind the brackets!!!
    		//further optimization [man, i am good today :D]
    		size_t sse_size = size  & ~3;
    		size_t pos;
    
    		__m128i* p_sse_source;
    		__m128i  sse_subtract_value;
    
    		if(/*start_pos%4 > 0*/ (begin_index & 3) > 0)
    		{
    			//sse_start_pos = start_pos+4 - start_pos % 4
    			sse_begin_index = begin_index+4 - (begin_index & 3); //remind the brackets!!!
    
    			for(pos = begin_index; pos<sse_begin_index && pos<=end_index; pos++)
    			{
    				vector.at(pos) -= subtract_value;
    			}
    		}
    		else
    		{
    			pos = sse_begin_index = begin_index;
    		}
    
    		sse_end_index = end_index - (end_index & 3);
    
    		//now start speedy SSE
    		if(sse_begin_index <= end_index)
    			p_sse_source = (__m128i*) &(vector.at(sse_begin_index));
    
    		sse_subtract_value = _mm_set1_epi32(subtract_value); //sse_subtract_value = add_value;
    
    		for( ; pos <= sse_end_index; pos+=4)
    		{
    			*p_sse_source = _mm_sub_epi32(*p_sse_source, sse_subtract_value); //p_sse_source[0,1,2,3] -= sse_subtract_value 
    
    			//go to the next
    			++p_sse_source;	
    		}
    
    		//now do the rest of the vector that could not be handled with SSE, because vector.size()%4 != 0
    		for( ; pos <= end_index; ++pos)
    		{
    			vector.at(pos) -= subtract_value;
    		}
    	}
    #endif
    

    Irgendwie funktioniert das ganze aber noch nicht 😞 .
    Wenn end_index = vector.size() ist, dann zieht er subtract_value nicht mehr vom letzten Element ab...

    Hat jemand ne Idee, wie man das ganze vielleicht einfacher angehen könnt. Langsam blicke ich da selber nicht mehr durch 😉



  • Hi, mal abgesehen davon das ich mal ganz flüchtig von SSE was gehört habe, habe ich dennoch ein paar Sachen zu bemerken.

    XCooperation schrieb:

    Wenn ich nun jetzt diesen Vektor habe:

    0, 1, 2, 3, 4, 5, 6, 7, 8
    

    ...
    end_index = vector.size()

    Ist dir klar das size() dir in diesem Falle 9 zurück geben würde.
    Dann wäre vec[9] ungültig.

    Zudem ist es gebräuchlich das man nicht End-Index übergibt, sondern eher die Anzahl, der ab begin_index zu löschenden Zeichen.
    Würde ich jedenfalls so machen.

    Hoffe mal, das ich dir etwas helfen konnte 🙂



  • Ups, ja klar, meinte natürlich:
    end_index = vector.size() - 1

    Naja, ich hab halt in meinem Programm als Eingabe nur end_index und nicht die Länge.
    Gut, die ließe sich ja berechnen:

    size = end_index - begin_index + 1
    

Anmelden zum Antworten