[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, 8dann sollte
SSE_Subtract(vector, 2, 4, 7)folgendes auswerfen:
0, 1, 2, 3, 2, 3, 4, 5, 8Bei 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; } } #endifIrgendwie 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() - 1Naja, 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