Re[6]: С/С++ вопрос.
От: Аноним  
Дата: 15.05.12 20:07
Оценка:
Здравствуйте, watch-maker, Вы писали:

_>>Вся проблема, в том как ефективно реализовать эту функцию.

__global__ void fn1_kernel ( float * result_array ) { value = fn1( x, y );  }
__global__ void fn2_kernel ( float * result_array ) { value = fn2( x, y );  }
....
__global__ void fnN_kernel ( float * result_array ) { value = fnN( x, y );  }

Пользователю позволить выбирать fn1 .. fnN
А так просто делаешь обычный компилятор для стековой машины (можешь глянуть книжку)
которая будет тебе генерить c-код для компилятора cudы
парсишь функцию и строишь граф вычислений. оптимизируешь граф (разные тождественные преобразования). генериш код по графу.
потом его в тихоря компилишь и загружаешь на исполнение.

на скорую руку для опытов, без оптимизации можно что-нибудь типа такого запилить
struct Compiler {
  Cgen cgen;
  Parser p;
  void compile() {
    compile_expression();
  }
  void compile_expression() {
    cgen.write("__global__ void expr_kernel ... {\n");
    r=0;
    int r1=L1();
    cgen.write("value=r%d;\n",r1);
    cgen.write("}\n");
  }
  int r; int allocReg(){ return ++r; }
  int L1() {
    int r1=L2();
    switch(p.get()) {
      case '+': { int r3=allocReg(); int r2=L2(); cgen.write("r%d=r%d + r%d;\n",r3,r1,r2); return r3; }
      case '-': { int r3=allocReg(); int r2=L2(); cgen.write("r%d=r%d - r%d;\n",r3,r1,r2); return r3; }
      ...
    }
    return r1;
  }
  int L2() {
    int r1=L3();
    switch(p.get()) {
      case '*': { int r3=allocReg(); int r2=L2(); cgen.write("r%d=r%d * r%d;\n",r3,r1,r2); return r3; }
      case '/': { int r3=allocReg(); int r2=L2(); cgen.write("r%d=r%d / r%d;\n",r3,r1,r2); return r3; }
      ...
    }
    return r1;
  }
  ...
  int L5() {
    if (p.check('(')) {
      int r1=L1();      
      if (!p.check(')')) throw_error("no closing )");
      return r1;
    }
    return L6();
  }
  int L6() { // digits, consts, variables, functions 
    int sign=+1;
    if (p.check('-')) sign=-1;
    int digit=p.getDigit();
    if (sign<0) digit=-digit;
    int r1=allocReg();
    cgen.write("r%d=%d;\n",r1,digit);
    return r1;
  }
}

единственно что у куды набор регистров ограничен и придётся оптимизировать, хотя если повезёт их компилятор выполнит эту работу за тебя.
но лучше почитай книжку.

_>>А использование интерпретатора, заметно снижает производительность, что воопще ставит под сомнение целесообразность использовать CUDA...

а нафига интерпритатор на куде? интерприти на пц и заливай в кодовские ядра готовый код.

WM>Если код может быть эффективно распараллелен, то CUDA позволяет его значительно ускорить. При этом будет ускоряться как изначально медленный, так и изначально быстрый код.

WM>Просто иногда дешевле переписать исходный код. А иногда дешевле запустить медленный код на GPU. А вот одновременно оптимизировать код и переписывать его на CUDA нужно реже. Хотя, конечно, выигрыш в производительности в последнем случае получается самым большим, с этим не поспоришь.
грамотно распараллелить это искусство. так что пиши в ручную.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.