Войти
ПрограммированиеФорумОбщее

Трюки с float: быстрое вычисление логарифмов. (комментарии)

Страницы: 1 2 3 Следующая »
#0
20:54, 16 апр. 2010

Трюки с float: быстрое вычесление логарифмов. (комментарии)

Это сообщение сгенерировано автоматически.


#1
20:54, 16 апр. 2010
Эксперимент 1: 58,533мс
Эксперимент 2: 57,398мс
Эксперимент 3: 348,635мс
Эксперимент 4: 369,977мс
Эксперимент 5: 150,350мс
Эксперимент 6: 38,044мс
1 и 2 - fastLog2 из подсказки
3 и 4 - logf
5 - sqrtf
6 - sqrt на sse

1) очевидно такую функцию как sqrt данным алгоритмом "ускорить" не удасться (можно только чуть замедлить и получить менее точный результат). аналогично с остальными функциями, которые есть в sse
2) как вычислить на sse логарифм - ненаю, потому в эксперименте он не участвовал. если кому не сложно - нарисуйте плиз (точности достаточно такойже, которая и у fastLog2)

#2
20:55, 16 апр. 2010
union ADVFLOAT
{
  float x;
  struct
  {
    unsigned int mant : 23; /* Mantissa without leading one */ 
    unsigned int exp  : 8;  /* Exponential part */
    unsigned int sign : 1;  /* Indicator of the negative number */
  };
};

#define LOG2E 1.44269504088896340736f

float fastLog2( float x )
{
  ADVFLOAT ax;

  ax.x = x;

  int exp = ax.exp - 127;
  ax.sign = 0;
  ax.exp = 127;

  return (ax.x - 1.0f) * LOG2E + exp;
}

float fastSqrt( float x )
{
  ADVFLOAT ax;
  int exp;

  ax.x = x;
  exp = ax.exp - 127;
  ax.sign = 0;
  ax.exp = 127;

  return (ax.x - 1.0f) * LOG2E + exp;
}

double GetTime()
{
  LARGE_INTEGER c,f;
  QueryPerformanceCounter(&c);
  QueryPerformanceFrequency(&f);
  long long ipart = c.QuadPart / f.QuadPart;
  long long fpart = c.QuadPart % f.QuadPart;
  return (double)ipart + (double)fpart / (double)f.QuadPart;
}

int _tmain(int argc, _TCHAR* argv[])
{
  setlocale(LC_ALL, "Russian");

  double time;
  const size_t arrlen = 10000000;
  __declspec(align(16)) float* src = new float[arrlen];
  __declspec(align(16)) float* dst = new float[arrlen];

  for(size_t i = 0; i < arrlen; i++) src[i] = (float)rand() / (float)RAND_MAX + (float)rand();
  
  for(size_t xxx = 0; xxx < 4; xxx++)
  {

    time = GetTime();
    for(size_t i = 0; i < arrlen; i++) dst[i] = fastLog2(src[i]);
    time = GetTime() - time;
    printf("Эксперимент 1: %.3fмс\n", time * 1000.0);

    __declspec(align(16)) float* _src = src;
    __declspec(align(16)) float* _dst = dst;
    time = GetTime();
    for(size_t i = 0; i < arrlen; i++) *_dst++ = fastLog2(*_src++);
    time = GetTime() - time;
    printf("Эксперимент 2: %.3fмс\n", time * 1000.0);

    time = GetTime();
    for(size_t i = 0; i < arrlen; i++) dst[i] = logf(src[i]);
    time = GetTime() - time;
    printf("Эксперимент 3: %.3fмс\n", time * 1000.0);

    _src = src;
    _dst = dst;
    time = GetTime();
    for(size_t i = 0; i < arrlen; i++) *_dst++ = logf(*_src++);
    time = GetTime() - time;
    printf("Эксперимент 4: %.3fмс\n", time * 1000.0);


    _src = src;
    _dst = dst;
    time = GetTime();
    for(size_t i = 0; i < arrlen; i++) *_dst++ = sqrtf(*_src++);
    time = GetTime() - time;
    printf("Эксперимент 5: %.3fмс\n", time * 1000.0);

    __declspec(align(16)) struct mms_rec { float r0, r1, r2, r3; };
    size_t arrlen2 = arrlen / 4;
    mms_rec* _src2 = (mms_rec*)src;
    mms_rec* _dst2 = (mms_rec*)dst;
    time = GetTime();
    for(size_t i = 0; i < arrlen2; i++)
      _mm_store_ps(&(_dst2++)->r0, _mm_sqrt_ps(_mm_load1_ps(&(_src2++)->r0)));
    time = GetTime() - time;
    printf("Эксперимент 6: %.3fмс\n", time * 1000.0);
  }

  return 0;
}
#3
23:09, 16 апр. 2010

вычисление

Heil Spellcheck!

#4
23:25, 16 апр. 2010

JokerR
> вычисление
ыыы. мну не заметил. модеры тоже =))
грамотные формучане не переживут позора и все уйдут на дтф =))

JokerR
> Heil
а это слово что значит? спелчекер должен был его подчеркнуть полюбому!

#5
0:27, 17 апр. 2010

JokerR
> вычисление
> Heil Spellcheck!
/facepalm.. сейчас поправлю :)))

Kloun
> а это слово что значит?
типа "my grammer is gooder" наврено :)

#6
8:56, 17 апр. 2010

Обратные корни и деление ускорять не надо, они и так быстрые, еще на K6 было 3 такта при половинной точности.

#7
9:04, 17 апр. 2010

Kloun
У тебя в коде тела функций fastLog2 и fastSqrt одинаковы :)

#8
11:12, 17 апр. 2010

Hartmann
> У тебя в коде тела функций fastLog2 и fastSqrt одинаковы :)
посто хотел сделать еще sqrt, но чет потом бросил

зы.
все-таки интересно. ктонибудь на see логарифм нарисует?

#9
13:34, 17 апр. 2010

JokerR
> Heil Spellcheck!
Тут Heil не из янки, а скорее из нацистко-германского. Типа Heil Hitler... хотя должно быть Hail Hitler...

#10
12:30, 18 апр. 2010

> Kloun

Да пусть в 10 раз медленнее работает и вообще толку нету. Совет всё равно очень интересный...

#11
12:38, 18 апр. 2010

Proteus
> Да пусть в 10 раз медленнее работает и вообще толку нету. Совет всё равно очень
> интересный...
интересный. ктоже спорит! а разобраться более досконально разве не иентересно?

#12
16:51, 18 апр. 2010

Kloun
> все-таки интересно. ктонибудь на see логарифм нарисует?
http://gruntthepeon.free.fr/ssemath/

#13
0:11, 24 апр. 2010

Стандартная функция C# System.Math.Log(double a) вычисляет 10000000 натуральных логарифмов в среднем за 610 мс. :) (на процессоре Turion X2).

#14
15:26, 10 мая 2010

hEil to the king babe?

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.