dev.gamez.lv Forum Index dev.gamez.lv
Latvian Game Developers Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups 

GPU izmantošana matemātiskiem aprēķiniem
Goto page 1, 2  Next
 
dev.gamez.lv Forum Index -> Programmēšana
View previous topic :: View next topic  
Author Message
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Sat May 13, 2006 8:13 pm    Post subject: GPU izmantošana matemātiskiem aprēķiniem

Ja nu kādu interesē GPU izmantošana ne tikai grafikas renderēšanai, bet gan izmantošana matemātiskiem aprēķiniem.. tad es te nedaudz paspēlējos un sarakstīju savus rezultātus.

Daudziem jau droši viens zināms, ka gan Nvidia, gan ATI daudzko stāsta par fizikas aprēķiniem uz GPU (videokartes procesora). Nvidias SDK ir daži piemēri kā tos izmantot specifiskām vajadzībām. Nesen ir jau izlaista pat speciāla PCI karte speciāli fizikas aprēķiniem (AGEIA PhysX). Visi cenšās noņemt aprēķinus no CPU un pārlikt tos citur. Nu lūk, es ar tā padomāju, ka moš jāpaskatās kā tas viss notiek uz GPU. Savu fizikas dzini diez vai uzrakstīšu uz GPU. Tāpēc iesākumam paņēmu kautko vienkāršu, bet grūti izskaitļojamu - matricu reizināšanu. Tā sarežģītība ir O(n^3), kur n ir matricas kolonnu/rindu skaits (kvadrātveida matricai). Ir zināms arī efektīvāks algoritms - ar O(n^(log2(7)) sarežģītību. Taču tas neimplementējas tik vielgi, prasa rekursiju un papildus atmiņu.

Pati reizināšana ir vienkāršu reizinājumu summa:
ja dota matrica A[1..n, 1..n] un B[1..n, 1...n], tad to reizinājums ir matrica C[1..n, 1..n], kurā katrs elements c[i,j] = a[i,1]*b[1,j] + a[i,2]*b[2,j] + ... + a[i,n]*b[n,j]. Varbūt ne gluži praktisks pielietojums fizikas dziņiem, taču tajos ietilpst darbošanās ar lielām matricām.
Tātad sāku vispirms ar algoritma uzrakstīšanu priekš parasta CPU (izmantojot float skaitļus, tāpēc darbības izpilda FPU - floating point unit):
Code:
void matmul_fpu(int n, const float* m1, const float* m2, float* m3)
{
  for (int i=0; i<n; ++i)
    for (int j=0; j<n; ++j)
    {
       float sum = 0.0f;
       for (int k=0; k<n; ++k)
         sum += m1[i*n+k] * m2[k*n+j];
       m3[i*n+j] = sum;
    }
}

Ļoti vienkāršs algoritms, vai ne?

Tad atcerējos par vienu citu labu lietu - SSE, kas ļauj apstrādāt 4 float vērtības ar vienu operācīju, it kā ļoti izdevīgi priekš šādas reizināšanas. Tad nu implementēju arī matricu reizināšanu ar SSE instrukcijām (funkcijas, kas sākas ar _mm_ apzīmē gandrīz 1:1 atbilstošas SSE assemblera instrukcijas):
Code:
void matmul_sse(int n, const float* m1, const float* m2, float* m3)
{
  for (int i=0; i<n; ++i)
    for (int j=0; j<n; j+=4)
    {
      __m128 sum = _mm_set1_ps(0.0);
      for (int k=0; k<n; k+=4)
      {
        __m128 x = _mm_load_ps(&m1[i*n+k]);
        _mm_prefetch(&m1[i*n+k+8], _MM_HINT_NTA);

        __m128 x1 = _mm_load_ps(&m2[(k+0)*n+j]);
        __m128 x2 = _mm_load_ps(&m2[(k+1)*n+j]);
        __m128 x3 = _mm_load_ps(&m2[(k+2)*n+j]);
        __m128 x4 = _mm_load_ps(&m2[(k+3)*n+j]);

        sum = _mm_add_ps(sum,_mm_mul_ps(_mm_shuffle_ps(x,x,_MM_SHUFFLE(0,0,0,0)), x1));
        sum = _mm_add_ps(sum,_mm_mul_ps(_mm_shuffle_ps(x,x,_MM_SHUFFLE(1,1,1,1)), x2));
        sum = _mm_add_ps(sum,_mm_mul_ps(_mm_shuffle_ps(x,x,_MM_SHUFFLE(2,2,2,2)), x3));
        sum = _mm_add_ps(sum,_mm_mul_ps(_mm_shuffle_ps(x,x,_MM_SHUFFLE(3,3,3,3)), x4));
      }
      _mm_stream_ps(&m3[i*n+j], sum);
    }
  _mm_empty();
}

Nedaudz sarežītāk, taču var redzēt, ka darbība notiek ņemot pa 4 skaitļiem uzreiz. Tīri teorētiski varētu sagaidīt 4 lielāku ātrumu, to varēs redzēt vēlāk, cik precīzi tas būs. Te jāpiebilst, ka SSE vislabāk darbojās ar floatiem četrīšiem atmiņā, kas izlīdzināti uz 16-baitu bloka. To GCC un MSVC nodrošina ar _mm_malloc un _mm_free funkcijām. Tādēļ uzrakstīju vienkāršu klasi, kas man dos šādu pointeri uz atmiņu (masīva sākuma), izlīdzinātu pēc 16 baitiem:
Code:
template <typename T, int align>
class AlignedArray
{
public:
  AlignedArray(int size) :
    _array(reinterpret_cast<T*>(_mm_malloc(size*sizeof(T), align))),
    _size(size)
  {
    assert(_array != 0);
  }
  ~AlignedArray() { _mm_free(_array); }

  operator const T* () const { return _array; }
  operator       T* ()       { return _array; }

  bool operator == (const AlignedArray<T, align>& other)
  {
    assert(_size == other._size);
    return std::search(_array, _array + _size,
                       other._array, other._array + _size,
                       float_compare) == _array;
  }

  // STL fju izsaukuma smukumam
  T* begin() { return _array; }
  T* end()   { return _array + _size; }

private:
  T* _array;
  int _size;

  static bool float_compare(const float f1, const float f2)
  {
    return std::fabs(f1 - f2) < 1e-4;
  }
};

typedef AlignedArray<float, 16> AlignedFloat16;

operators == nodrošina masīvā saglabāto vērtību salīdzināšanu (lai pārbaudītu matricu reizinājumu ar dažādām metodēm). Tātad tagad mums ir AlignedFloat16 klase, kas uzvedās gandrīz kā parasts float masīvs.

Tagad nedaudz par GPU darbības principiem.
Es ņēmu par pamatu OpenGL 2.0 versiju un tās piedāvātos GLSL valodā rakstītos šeiderus. Matricas elementus es ieliku tekstūrās un, zīmēju vienu lielu kvadrātu uz "ekrāna", kuru uzskatu par rezultātā iegūto matricu - C. Katram "ekrāna" pikselim (matricas elementam) tiek laists fragment shader, kurš no pikseļa koordinātes uz "ekrāna" izrēķina matricas rindu/kollonu un no citām divām tekstūrām, kurā saliktas A un B matricas, ņem izejas datus un darbojās reizinot/saskaitot. Vārds "ekrāns" tiek likts pēdiņās, jo īstenībā uz ekrāna es jau neko nezīmēju. Visu zīmēju freimbufferī, kurš atrodas atmiņā (tekstūra). tam izmantoju Framebuffer Object - relatīvi nesen ieviesto OpenGL paplašinājumu, kas atļauj šādas darbības, par to sīkāk zemāk. Pats šeideris izskatās šāds:
Code:
uniform int n;
uniform sampler2D m1;
uniform sampler2D m2;

void main()
{
  vec2 pos = gl_TexCoord[0].st;

  vec4 summ = vec4(0.0, 0.0, 0.0, 0.0);

  float invN = 1.0/(n-1);

  float i_tex = 0.0;
  for (int i=0; i<n; i+=4)
  {
    vec4 pix1 = texture2D(m1, vec2(i_tex, pos.y));

    vec4 p1 = texture2D(m2, vec2(pos.x, i_tex)); i_tex += invN;
    vec4 p2 = texture2D(m2, vec2(pos.x, i_tex)); i_tex += invN;
    vec4 p3 = texture2D(m2, vec2(pos.x, i_tex)); i_tex += invN;
    vec4 p4 = texture2D(m2, vec2(pos.x, i_tex)); i_tex += invN;

    summ += vec4(
                 dot(pix1, vec4(p1[0], p2[0], p3[0], p4[0])),
                 dot(pix1, vec4(p1[1], p2[1], p3[1], p4[1])),
                 dot(pix1, vec4(p1[2], p2[2], p3[2], p4[2])),
                 dot(pix1, vec4(p1[3], p2[3], p3[3], p4[3]))
                );
  }

  gl_FragColor = summ;
}

Var redzēt, ka notiek koordinātes pārrēķināšana no 0..n-1 (matricas elementu koordinātes robežas) uz 0..1 (kas ir tekstūras koordinātes).
Darbošanās notiek pa 4 pikseļiem uzreiz, jo tekstūras glabā sevī krāsas attēlojumu kā RGBA - 4 vērtības. Tādējādi var izdevīgāk izmantot šeidera piedāvātās iespējas - saskaitīšanu/reizināšanu ar 4 skaitļiem uzreiz, nevis pa vienam. Tiek iegūts papildus ātrums. texture2D ir tā fja, kas veic lookupu tekstūrā, kuras identifikators tiek padots pirmajā argumentā, un divdimensiju koordinātes, no kurienes nolasīt pikseli, otrajā argumentā. dot ir vektoru skalārais reizinājums.
Vertex šeideris izskatās vienkāršs, man nevajag nekādas vertex'u transformācijas. Vienīgais, ko vajag, ir pikseļa koordinātes, kuras saglabāju gl_TexCoord[0] mainīgajā:
Code:
void main()
{   
  gl_Position = ftransform();
  gl_TexCoord[0] = gl_MultiTexCoord0;
}


Par pašu Freimbuffer izveidi un šeideru izsaukšanu.
Vispirms izveidoju dummy logu. Parastais CreateWindows/GetDC/ChoosePixelFormat/SetPixelFormat/wglCreateContext/wglMakeContext - atrodams daudzos OpenGL tutoriāļos. Nekas svarīgs. Tad pielādēju vajadzīgos paplašinājumus, kā jau iepriekš minēju vajadzīga ir videokarte, kas atbalsta OpenGL 2.0 versiju, tad visdrīzāk nebūs problēmu (ja nu vienīgi ar ATI videokartēm ;). Tātad nepieciešamie extensioni GL_ARB_multitexture (vairākām tekstūrām=matricām pie renderēšanas=rēķināšanas), GL_ARB_texture_float (matricā vajag saglabāt float tipa datus), GL_EXT_framebuffer_object (freimbufferis, kurā notiek renderešana), GL_ARB_fragment_shader, GL_ARB_vertex_shader GL_ARB_shader_objects, GL_ARB_shading_language_100 (GLSL atbalsts).
Pēc šī visa izdarīšana izveidoju Freimbufferi izmērā, kāda ir gala matrica - n/4 platumā un n augstumā. Platums tiek dalīts ar 4, jo viens pikselis satur 4 krāsas komponentes - RGBA, tātad 4 maticas elementus. Freimbufferis tiek izveidots līdzīgi kā tekstūra - glGen, glBind. Tikai papildus tam tiek piesaistīta tekstūra, kurā tas renderēs visu pasākumu (to vēlāk var izmantot arī renderēšanai, to izmanto, piemēram, HDR efektu iegūšanai, bet man tas nebūs vajadzīgs). Pēc tam pielādēju abus iepriekš uzrakstītos šeiderus, nokompilēju/salinkoju abus. Kad tas bija gatavs, tad pati matricu rēķināšana=renderēšana notiek šādi:
Code:
// pasaka, ka visa renderēšana notiks freimbuferī, nevis uz ekrāna
// un aktivizē šeideru programmu
void GPUprogram::begin() const
{
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  glUseProgramObjectARB(program);
}

// pati zīmēšana
void GPUmatmul::render() const
{
  setInteger("n", n);  // uzstāda šeidera parametrus
  setInteger("m1", 1); // tur tiek izmantota glUniform1iARB fja
  setInteger("m2", 2);

  // pirmajā tekstūru unitā upload m1 tekstūras elementus
  glActiveTextureARB(GL_TEXTURE0_ARB + 1);
  glTexImage2D(texture_target, 0, texture_internal, n/4, n, 0, texture_format, GL_FLOAT, m1);

  // otrajā tekstūru unitā upload m2 tekstūras elementus
  glActiveTextureARB(GL_TEXTURE0_ARB + 2);
  glTexImage2D(texture_target, 0, texture_internal, n/4, n, 0, texture_format, GL_FLOAT, m2);

  // pasaka, ka renderēšana notiks 0-tajā freimbuffera attačmentā
  glActiveTextureARB(GL_TEXTURE0_ARB);
  glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

/***/

  // uzstāda ortogonālu projekciju
  // kur viens freimbuffera pikselis atbilst precīzi vienam matricas elementam
  glViewport(0, 0, n/4, n);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, n/4, 0, n);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  // uzzīmē vienu lielu taisnstūri
  glEnable(texture_target);
  glBegin(GL_QUADS);
  {
    glTexCoord2i(0, 0); glVertex2i(  0, 0);
    glTexCoord2i(1, 0); glVertex2i(n/4, 0);
    glTexCoord2i(1, 1); glVertex2i(n/4, n);
    glTexCoord2i(0, 1); glVertex2i(  0, n);
  }
  glEnd();

/***/

  // nolasa norenderētos pikseļus no freimbuffera
  glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
  glReadPixels(0, 0, n/4, n, texture_format, GL_FLOAT, m3);
}

// atslēdz šeideru programmu un renderēšanu freimbufferī
void GPUprogram::end() const
{
  glUseProgramObjectARB(0);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

Dažas no izmantotajām konstantēm:
Code:
static const int texture_target   = GL_TEXTURE_2D;
static const int texture_format   = GL_RGBA;
static const int texture_internal = GL_RGBA32F_ARB;

texure_target būtu jāmaina uz citu tekstūras tipu, ja matricas elementi nebūs skaitļa 2 pakāpes, jo tad tie būs nederīgi izmēri tekstūrai.

To visu esmu, protams, saliecis attiecīgās klasēs. Klases centos veidot universāli, lai varētu darbināt dažādus algoritmus (ne tikai matricu reizināšanu).

Pati galvenā main funkcija (tb programma) visai testēšanai izskatās šāda:
Code:
int main(void)
{
  std::auto_ptr<GPUmath>   gpu_math;
  std::auto_ptr<GPUmatmul> gpu_matmul;

  AlignedFloat16 m1(test_size2);
  AlignedFloat16 m2(test_size2);
  AlignedFloat16 m3_fpu(test_size2);
  AlignedFloat16 m3_sse(test_size2);
  AlignedFloat16 m3_gpu(test_size2);

  try
  {
    gpu_math.reset(new GPUmath());
    gpu_matmul.reset(new GPUmatmul(test_size, m1, m2, m3_gpu));
  }
  catch (const std::string& error)
  {
     std::cout << "GPU error: " << error << std::endl;
  }

  std::srand(time(0));
  std::for_each(m1.begin(), m1.end(), setRandom);
  std::for_each(m2.begin(), m2.end(), setRandom);

  Timer t;

  matmul_fpu(test_size, m1, m2, m3_fpu);
  double elapsed_fpu = t.time();

  std::cout << "FPU matmul: " << elapsed_fpu << " secs. " << std::endl;

  t.reset();
  matmul_sse(test_size, m1, m2, m3_sse);

  double elapsed_sse = t.time();

  std::cout << "SSE matmul: " << elapsed_sse << " secs. "
            << (m3_fpu == m3_sse ? "OK." : "WRONG!") << std::endl;

  if (gpu_math.get() && gpu_matmul.get())
  {
    t.reset();
    gpu_math->run(gpu_matmul.get());
    double elapsed_gpu = t.time();

    std::cout << "GPU matmul: " << elapsed_gpu << " secs. " << std::endl;
              << (m3_fpu == m3_gpu ? "OK." : "WRONG!") << std::endl;
  }

  return 0;
}

Palaižot to visu uz šādas konfigurācijas datora Pentium M 730 1.6Ghz (oc uz 2.5Ghz), GeForce 6800GT 256mb (liels paldies darba kolēģim, kurš uzņēmās šo testēšanu uz sava datora. Mans dators ir dikti aizvēsturisks ;) esmu ieguvis šādus rezultātus:
Code:
FPU: 51.39  secs.
SSE: 13.811 secs
GPU:  0.652 secs

Tātad - SSE ieguvums ir 3.72 reizes, un GPU ieguvums ir 78.8 reizes. Reizinātas tika 1024x1024 matricas. Spēcīgi skaitļi, vai ne?
Kompilēšanai izmantoju GCC ar šādiem optimizācijas parametriem: -O2 -march=i686 -msse

Vēl daži secinājumi par GPU darbību - lasot dažādu informāciju netā un eksperimentējot ar šeideriem esmu secinājis, ka GPU vislabāk strādā ar float datu tipa skaitļiem, tas ir viņu, tā teikt, natīvais formāts. Ar integeru ir pašvakāk (nav shift, and, or, xor, not operācijas). Vislabāk ar to apstrādāt daudz datus, kuriem jāpielieto viendabīgs (nu viena veida) algoritms, kam protams atbilst spēļu grafika.
Kā mīnusu varu minēt nelielas atšķirības float skaitļu aritmētikā, tb atšķirības no fpu skaitļiem pie vienādām operācijām. Bet to visdrīzāk var novelt uz apaļošanas atšķirībām starp fpu un gpu. Ļoti ticami, ka to var piekoriģēt tā, lai atšķirības būtu vēl mazākas, taču kritiski domāju tas nav. Vēl, protams, arī tas domāšanas veids - datu masīvs=tekstūra, algoritms=šeiders, rēķināšana=trijstūru/četrstūru zīmēšana. Pie tāda nedaudz jāpiešaujas ;)

Komentāri? Ieteikumi? Ja interesē pilns source kods, tad varu to iedot uz pieprasījumā, nosūtiet man PM. Kā jau iepriekš minēju, par kompilatoru izmantoju GCC 3.4.5 Windows variantu. Taču gan jau arī uz MSVC un noportēšanai uz Linux nevajadzētu būt problēmām. Vienīgā atšķirība Linux OS būtu starp loga izveidošanā, kas neaizņem daudz koda.


Last edited by bubu on Sat May 13, 2006 9:42 pm; edited 2 times in total
Back to top
View user's profile Send e-mail
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Sat May 13, 2006 9:39 pm    Post subject:

Pirmkaart-kapec starp FPU un SSE ir taadas atshkjiriibas?Musdienu kompileri tak standarta izmanto SSE.Vai varbuut GCC neizmanto?Pameegjini shito uz VC++.
Un otrkaart-kapec izmantoji pixel shaderi?Parasti tak fiziku reekjina ar vertex shaderi.Un taa arii buutu vienkaarshaak-padod konstanti ar matricu vertex sheiderim un izdari apreekjinus.
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Sat May 13, 2006 11:38 pm    Post subject:

AFAIK kompilatori izmanto SSE ģenerētajam kodam, ja tie māk "ieraudzīt", ka to kodu var pārveidot uz SSE, un tādi gadījumi ir manuprāt tikai triviālākie. Acīmredzot šāds kods nav viegli ieraugāms šajā gadījumā, nemaz nerunājot par sarežģītākām operācijām. Cilvēka rakstītu asm'u nekad diez vai pilnībā var aizstāt kompilators.

Pamēģināju programmu nokumpilētu uz MSVC++ 2005. Visi optimizācijas settingi - uz ātrumu. Tas pats - aptuveni 4x ātrāks ir SSE kods, precīzāk 3.87 reizes.

Par tiem šeideriem - a kas vainas fragment šeiderim? Un tavs "parasti tak fiziku rēķina ar vertex shaderi" lika pabrīnīties. Kas ir parasti? Vai tad tik daudz cilvēku jau raksta fizikas dziņus uz GPU?
Pie tam neesmu redzējis nevienu programmas sourci fizikas rēķināšanai uz GPU, lai spriestu, kas ir parasti un kas nē. Man tas likās dabiskāk, ka tiek zīmēts teksturēts quads - C matrica, kura veidojās no A un B matricu (2 tekstūrām) reizinājuma. Veids kā es varēju "salikt" pikseļu krāsas rezultāta matricā ir izdarāms caur fragment šeideri, ne vertex. Un vēl jau arī tas, ka šis ir mans pirmais šeideris, kuru esmu uzrakstījis :) Iepriekš par šeideriem neko daudz nezināju.
Back to top
View user's profile Send e-mail
dev



Joined: 27 Jul 2004
Posts: 206
Location: Latvija

PostPosted: Sat May 13, 2006 11:54 pm    Post subject:

A kaada ir aatrumu atskjiriiba ja izmanto jau sheidera gatavo komandu matricu reizinaashanai (HLSL mul)? Saprotu, ka eksperimenta meerkjis bija notesteet universaalu skaitljoshanu, vnk iedomaajos vai jau gatavaa komanda ir mega aatraaka.. taa jau rezultaats shitam iespaidiigs - nebiju domaajis ka taa buus, domaju ka nolasiishana/ierakstiihana freimbuferii visu nobremzees, bet nu iespaidiigi Smile
Back to top
View user's profile Visit poster's website MSN Messenger
BHC



Joined: 31 Jan 2006
Posts: 81

PostPosted: Sun May 14, 2006 12:03 am    Post subject: Re: GPU izmantošana matemātiskiem aprēķiniem

Quote:

Code:
void matmul_fpu(int n, const float* m1, const float* m2, float* m3)
{
  for (int i=0; i<n; ++i)
    for (int j=0; j<n; ++j)
    {
       float sum = 0.0f;
       for (int k=0; k<n; ++k)
         sum += m1[i*n+k] * m2[k*n+j];
       m3[i*n+j] = sum;
    }
}

Ļoti vienkāršs algoritms, vai ne?

Vienkāršs, bet optimizējams.

Var atbrīvoties no trīs nevajadzīgām integer reizināšanām.
Mainīgais n ir konstants visiem cikliem.
Kas nozīmē, ka varam ieviest mainīgos, kuriem attiecīgajos ciklos(i, k) tiks summēts klāt n.

for (int i=0; i<n; ++i)
for (int j=0; j<n; ++j)
{
float sum = 0.0f;
for (int k=0; k<n; ++k)
sum += m1[i*n+k] * m2[k*n+j];
m3[i*n+j] = sum;
}

Un cikla mainīgos es salīdzinātu ar nulli.
Tās pašas optimizācijas attiecas arī uz sse variantu.

Cik liels būs performances gain's, ir cits jautājums.
Ja nekļūdos, ietaupam 1024x1024x1024x2 + 1024x1024 integer reizināšanas. :)

Es pēc iespējas atturos no asm/sse/etc optimizācijām, it īpaši GPU optimizācijām, par kurām es ne-bum-bum.
Turos pie klasiskajām optimizācijām, kuras man jau tā ļoti reti nākas izmantot.

BTW, Bubu taisa piekto kveiku? Very Happy
_________________
Screenshot coming when hell freezes over.
Back to top
View user's profile
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Sun May 14, 2006 6:59 am    Post subject:

dev wrote:
A kaada ir aatrumu atskjiriiba ja izmanto jau sheidera gatavo komandu matricu reizinaashanai (HLSL mul)?

Neizmantoju HLSL, bet gan izmantoju GLSL. Un matricu reizināšanas komanda man īsti labi neder. Jo vajag reizināt skaitļu pārīšus, nevis 4x4 matricu.

BHC wrote:
Vienkāršs, bet optimizējams.

Protams. Daudzkas tur optimizējams, arī šeideris. Vēl jau der paskatīties arī uzģenerētājā asm kodā, varbūt tur jau daudzkas optimizēts ;)
Lai nu kā, bet nedomāju, ka tas mainīs algoritma sarežģītību, tb laiks nu noteikti nemainīsies vairāk kā 2x.
Back to top
View user's profile Send e-mail
S1
Indago dalībnieks
Indago dalībnieks


Joined: 31 Jul 2005
Posts: 219
Location: Jelgava

PostPosted: Sun May 14, 2006 9:48 am    Post subject:

iespaidīgi Shocked
Man ienāca prātā, vai ar GPU nevar aizstāt skaņas karti? Very Happy
Back to top
View user's profile Send e-mail
Kamazs
Guru
Guru


Joined: 17 Jan 2003
Posts: 829
Location: The glorious ancient city of Loja

PostPosted: Sun May 14, 2006 10:10 am    Post subject:

Fantastika, bubu...~80x.. GEM aprēķiniem ideāli..džī..
_________________
...un es uzskatu, ka Fallout ir etalons
Back to top
View user's profile Send e-mail Visit poster's website
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Sun May 14, 2006 10:43 am    Post subject:

Cik lasiju,tad kompilators visas operaacijas ar float[4] paarveido uz SSE.Bet nu neesmu njeemies un testeejis shito.

Ar vertex shaderi parasti reekjina objektu animaacijas utt. tapec biju iedomaajies,ka arii fiziku buutu vieglaak rekjinaat.Bet pamekleeju info netaa un atradu paaris forumus,kur arii atbalstija fizikas reekjinaashanu ar pixel shaderi.Taka no offense.

Vispar-3D Game engine programming (kas ir diezgan paveca graamata) saka,ka vajag sabalanseet apreekjinus starp video karti un procesoru.Un ja reiz tajos senajos laikos (2003. gads) ciiniijas ar video kartes paarslogotiibu,tad fizikas uzgruushana uz video kartes vispaar buutu nepraats.Bet nu Shader Model 4 buus Geometry Shader,kas vien noziimee,ka fizika vareetu paariet uz video kartes.Laikam to,kas notiks, tikai laiks raadiis.
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon May 15, 2006 8:23 am    Post subject:

S1 wrote:
iespaidīgi :shock:
Man ienāca prātā, vai ar GPU nevar aizstāt skaņas karti? :D

Aizstāt nē, jo diez vai videokarte skanēt sāks, tur sarežģītas tumbas būtu jātaisa, taču skaņas apstrādes filtrus taisīt jā kāpēc ne. Tas pats arī ar attēla/video apstrādes filtriem.

Kamazs wrote:
GEM aprēķiniem ideāli..džī..

Kas ir GEM?
Back to top
View user's profile Send e-mail
Kamazs
Guru
Guru


Joined: 17 Jan 2003
Posts: 829
Location: The glorious ancient city of Loja

PostPosted: Mon May 15, 2006 9:12 am    Post subject:

GEM latviski jeb FEM angliski -- galīgo elementu metode (finite elements). Populāra diferenciālvienādojumu tuvinātā risināšana (alternatīva galīgajām diferencēm un citām metodēm). Tur vajag risināt integrāļus un LAVS -- ja pareizi sapratu, kaut kas akurāt līdzīgs šai matricu reizināšanai.
_________________
...un es uzskatu, ka Fallout ir etalons
Back to top
View user's profile Send e-mail Visit poster's website
Vecais_Dumais_Laacis
Guru
Guru


Joined: 29 Jan 2004
Posts: 800

PostPosted: Mon May 15, 2006 9:49 am    Post subject:

speeciigi Wink
_________________
...un ja bites buutu laachi...
Back to top
View user's profile
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon May 15, 2006 12:39 pm    Post subject:

Kamazs wrote:
Populāra diferenciālvienādojumu tuvinātā risināšana (alternatīva galīgajām diferencēm un citām metodēm).

Ā pareizi, atceros šitādu lietu. Man to Kalis mācīja, tik ja pareizi atceros, to sauca par diferenču vienādojumiem.
Back to top
View user's profile Send e-mail
Kamazs
Guru
Guru


Joined: 17 Jan 2003
Posts: 829
Location: The glorious ancient city of Loja

PostPosted: Mon May 15, 2006 3:03 pm    Post subject:

GEM un diferences ir dažādas lietas, bet katrā ziņā GEM(FEM) ir viena no tām metodēm, kuras izmanto tīri praktiskiem(komerciāliem) mērķiem fizikālajā modelēšanā. Anyways, ļoti vērtīgs darbs, bubu, tiešām vērtīgi, tas var izrādīties ļoti noderīgi ne tikai gameDEVā.
_________________
...un es uzskatu, ka Fallout ir etalons
Back to top
View user's profile Send e-mail Visit poster's website
EDDY



Joined: 07 Oct 2005
Posts: 1610
Location: Dzimtā zeme, Latvija

PostPosted: Mon Feb 05, 2007 10:55 am    Post subject:

Sorry, ka uzceļu tēmu no miroņiem, bet tā lieta mani ieinteresēja.
Cik no testa rezultātiem skatos, tad atkarībā no videokartes un CPU atbilstības tad arī izveidojā tas n-tais pieaugums.
Man tas nepārsniedz ~12 reizes.
Bet precīzāk -
CPU - 1,078 s,
SSE - 0,26 s,
GPU - 0,09 s.

Bet jautājums ir šāds - Kur reāli to var izmantot? Vai tikai rotējošam kubam/plaknei, kuru piemēri ir atrodami? Un kā iet kopā, ja shader instrukcijas jau ir noloslogotas uz grafiku? Mani interesē, vai nezudīs ievērojama datorjauda, ja paralēli noslogosim bump, ēnas u.c. aprēķinus ar šo GPU pielikšanu? Te tiek runāts par matricu reizināšanu, taču nedz ATI, nedz nVidia par SSE neko laikam nav dzirdējuši. Sorry, ka jaucu abas lietas vienā kastē, bet to visu var apvienot. + kā bubu man teica, arī otra CPU kodola ielikšana dod pieaugumu par max. 180%.

Gribētos to visu redzēt vienā nelielā piemērā: SSE + Dual Core tehnoloģija + GPU. Lasīt internetā jau var, bet te drīzāk nepieciešama vesela grāmata par šo tēmu.
_________________
Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday
Back to top
View user's profile
Display posts from previous:   
dev.gamez.lv Forum Index -> Programmēšana All times are GMT + 2 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group