Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

11

04.05.2009, 23:15

Die Frage ging eher in die Richtung: Hast du denn überhaupt etwas, was schon an die Grenzen heutiger PCs kommt? (und ich rede hier nicht von versteckten while(1) Schleifen). ASM ist so ne Sache. Da sollte man wirklich Ahnung von haben ehe man das einsetzt. Es gibt halt die überaus interessante Grundüberlegung "premature optimization is the root of all evil.".
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

VuuRWerK

Frischling

Beiträge: 59

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

12

05.05.2009, 00:57

Da ich mich auch schon eine weile damit beschäftige habe ich mal fix eine Beispiel-Implementierung für die Nutzung von Intrinsics gemacht.

Kurze vector-klasse:

C-/C++-Quelltext

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
#ifndef __VECTOR3_HPP___
#define __VECTOR3_HPP___

#include <xmmintrin.h>

template< typename TypeT >
class vector {
public:
  vector(TypeT x_, TypeT y_, TypeT z_)
    : x(x_)
    , y(y_)
    , z(z_) {}

  TypeT dot(vector< TypeT > other) {
    return x * other.x + y * other.y + z * other.z;
  }

  TypeT dot_sse(vector< TypeT > const& other) {
    TypeT v1_sse_in[3] __attribute__((aligned(16))) = { x, y, z };
    TypeT v2_sse_in[3] __attribute__((aligned(16))) = { other.x, other.y, other.z };
    TypeT v_sse_out[3] __attribute__((aligned(16)));

    __m128 a, b, c;
    a = _mm_load_ps(v1_sse_in);
    b = _mm_load_ps(v2_sse_in);
    c = _mm_mul_ps(a, b);
    _mm_store_ps(v_sse_out, c);

    return v_sse_out[0] + v_sse_out[1] + v_sse_out[2];
  }

  TypeT x;
  TypeT y;
  TypeT z;
};

typedef vector< float > vector3f;
typedef vector< double > vector3d;

#endif // __VECTOR3_HPP___


Programm zum Testen (mit nanosekunden-genauer Zeitmessung):

C-/C++-Quelltext

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
#include <iostream>
#include <iomanip>

#include "vector3.hpp"

typedef unsigned long long tsc_t;

static inline tsc_t read_tsc() {
  tsc_t tsc;
  __asm__ __volatile__ ("rdtsc": "=A"(tsc));
  return tsc;
}

int main(int argc, char* argv[]) {
  vector3f v1(1.0f, 2.0f, 3.0f);
  vector3f v2(4.0f, 5.0f, 6.0f);
  float dot_product;
  tsc_t start, end;

  start = read_tsc();
  dot_product = v1.dot(v2);
  end = read_tsc();
  std::cout << "ordinary version: " << dot_product
            << ", Time: " << std::setprecision(4)
            << (end - start) << "ns." << std::endl;
  start = read_tsc();
  dot_product = v1.dot_sse(v2);
  end = read_tsc();
  std::cout << "sse version: " << dot_product
            << ", Time: " << std::setprecision(4)
            << (end - start) << "ns." << std::endl;
  return 0;
}


Ausgabe auf meine Rechner (CPU: Q6600, kompiliert mit g++ 4.3.3-dw2-tdm-1, flags: -msse -O0):

Quellcode

1
2
ordinary version: 32, Time: 1386ns.
sse version: 32, Time: 378ns.


und jetzt mit -O3:

Quellcode

1
2
ordinary version: 32, Time: 63ns.
sse version: 32, Time: 270ns.


Wie man sieht kann der Compiler eindeutig besser Optimieren als wenn man mit hardwarenahem SSE ran geht. SSE ist nur dann besser wenn man den Compiler, warum auch immer, nicht optimieren lässt. Denke SSE und Co. haben ihre Stärken auf anderer Ebene aber eben nicht beim optimieren des Punktprodukts eines Vektors :)

Gut Schuß
VuuRWerK ;)

[edit]Mir viel noch folgendes ein: Vielleicht sollte man das ganze nochmal testen mit nicht-konstanten Werten, denke zwar das der Compiler dennoch besser optimiert aber man könnte ja mal schaun wie nach man mit SSE rankommt :) Ich probier das dann mal sobald ich daheim bin.[/edit]
http://german-bash.org/212445
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." - Bjarne Stroustrup

13

05.05.2009, 16:32

Problem ist: Du müsstest das wahrscheinlich auf mehrere Prozessoren und so testen, um genauer beurteilen zu können, wo es wie schnell ist.
Lieber dumm fragen, als dumm bleiben!

Werbeanzeige