LINUX.ORG.RU

Производительность; илитный запил оптимальных реализаций и основы матчасти.

 , , ,


21

17

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

Это будет формат для самых маленьких, где я буду показывать как что-то пилится по-пацаночке. Его задача - на примерах пересказать штеудмануал тем, кому лень его читать, но кто очень любит спорить про код, перфоманс и матчасть. Ну и просто интересные наблюдения.

Изначально я хотел написать про то: что такое бесплатные вычисления на примере is_range() + сумма елементов массива, но тут выявилась смешная особенность, поэтому пока без is_range().

Начнём с простого - сумма елементов(float) массива. Как написать её быстро? Обычный крестопоц сделает так:

auto summ = accumulate(begin(vec), end(vec), 0.)

Этот код выдаёт 5.6GB/s(мы всё бенчим в л1д 32килобайта массив). Казалось бы, если бы мы слушали всяких «гуру», которые нам говорят: accumulate() - оптимизирован, «ты что умнее создатели stl"а?», «конпелятор умнее тебе - сам всё делает оптимально», «руками что-то делать слишком сложно и не нужно» - то мы бы там и остались с этими 5.6ГБ, но мы пойдём дальше и поймём почему так, и является ли это тем, что намн ужно.

Но посмотрев на код - он не векторизован:

	addq	$4, %rdx
	vcvtss2sd	-4(%rdx), %xmm2, %xmm2
	vaddsd	%xmm2, %xmm1, %xmm1

Почему? Патамучто это основная флоатпроблема: Он не ассоциативен - флоат не имеет в себе точных представлений всех чисел входящих в диапазон его «представления» т.е. порядкопроблемы.

Поэтому конпелятор НЕ ВЕКТОРИЗУЕТ флоат по умолчанию, ну никак. Даже такую банальщину.

Для решения этих проблем - есть ключик -funsafe-math-optimizations, который входит в -ffast-math, который кладёт на точность при вычислениях. Добавив его мы получаем уже 44.9GB/s.

Но теперь мы получаем ещё одну проблему - надо думать: «как бэ сунуть эту ключик не повредив там, где этот ключик не нужен».

Поэтому ноцанам, которые хотят быстро и не хоятт рандомных жоп из-за тупости конпелятора - пишут всё руками. Допустим на той же сишке это пишется так:

double memadd_autovec(buf_t buf) { //5.609465GB/s, либо 44.969652GB/s с ffast-math
  float * it = buf_begin(buf), * end = buf_end(buf), summ = 0.;
  do {
    summ += *it++;
  } while(it != end);
  return summ;
}

double hsumf(__v8sf v) {
  return (v[0] + v[1] + v[2] + v[3] + v[4] + v[5] + v[6] + v[7]);
}

double memadd_vec(buf_t buf) { //45.652002GB/s и класть на ffast-math
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ += *it++;
  } while(it != end);
  return hsumf(summ);
}

Т.е. разницы никакой нет, кроме нужной нам реализации горизантального сложение вектора. Когда я говорил пацану: «векторную сишку для написания быстрого кода юзать намного проще, чем плюсы» - поцан нипонимэ, да и любые пацаны скажут - ну дак с -ffast-math оба выдают по 45гигов - нахрен эта сишка нужна?

А вот зачем:

double memadd(buf_t buf) { //132.878440GB/s
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ += *it++;summ += *it++;summ += *it++;summ += *it++;
  } while(it != end);
  return hsumf(summ);
}

Это называется пацанский анролл копипастой, а вот заставить конпелятор нормально что-то разанролить очень сложно.

Если бы мы слушали всяких «гуру», которые нам вещают: «анрол говно и не нужен» - мы бы так и седели с 45-ю гигами, а так мы сидим с 132.878440GB/s. Т.е. анролл нам дал немного не мало ~300%.

Но основная мысль, которую толкают всякие «гуру» - это не надо следить за тактами/считать такты и прочее. Но мы о5 сделаем наоборот и посмотрим что будет.

Т.к. наш юзкейс упирается на 99% в throughput и дёргается одна инструкция, то нам достаточно просто считать теоретическую производительность для моего камня. 4.5(частота камня)*8(т.е. у нас камень с avx, то там вектор 32байта, либо 8флоатов.)*1(throughput нашей инструкции - в данном случае vpaddps из интел мануала). Т.е. 36гигафлопс, либо ~144гига. Т.е. мы сняли овер 90% теоретической производительности - остальные 10% у нас ушли в наши циклы, всякие горизонтальные суммы вектора и прочее, ну и конечно же чтение данных из кеша.

Но самое смешное - на моём хасвеле умножение имеет throughput 0.5 - т.е. на хасвеле умножение быстрее сложения. Это новая забористая трава у интела.

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

Поэтому очень смешно слушать, когда какие-то пацаны говорят: «float point имеет такую же производительность как и инты» - нет, оно имеет такоу же производительность лишь по причине того, что на штеуде инты тормазят так же, как и float.

И чтобы окончательно в этом убедится - мы взглянем на fma(вариации умножения со сложением/вычитанем), которые имеют throughput 0.5 - да, да - на хасвеле умножение+сложение в 2раза быстрее просто сложения. Это уже не просто трава - это что-то принципиально новое.

У целочисленного сложения же throughput 0.5 и казалось бы, если мы поменяем в нашей функции float на int - у нас будет сложение работать в 2раза быстрее, но это не так. Оно выдаёт те же 130гигов, а почему?

Вообще у камня есть такая фича, допустим у нас:

add $1, %reg0//вот тут инструкция add залочит регистр reg0
add $1, %reg0//а эта инструкция уйдёт в лок до особождения предыдущей инструкцией регистра reg0

Чтобы такой жопы небыло - есть специальная фича:

add $1, %reg0//lock reg0
add $1, %reg0//И тут вместо того, чтобы уйти в лок - камень вместо reg0 даёт инструкции любой свободный регистр.

Эта фича называется прееименование регистров, либо как-то так - мне лень гуглить.

Дак вот штука в том, что фича работает через жопу. Мне лень читать мануал и искать почему так, но штука в том, что она ограничивает throughput. На умножении и целочисленном сложении она огранивает throughput c 0.5 до 1.

И вот я решил заюзать сложении через fma:

__v8sf fmaadd(__v8sf a, __v8sf b) {
  return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);// a + b * 1. == a + b.
}

double memadd_fma(buf_t buf) {
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ = fmaadd(summ, *it++);
  } while(it != end);
  return hsumf(summ);
}

Но меня ждала жопа: 27.347290GB/s, причем не анролл и ничего не помогал. Я уж подумал, что мануал наврал, но позже до меня допёрло: у неё latency 5тактов и ((4.5×8)÷5)×4 ~= 29гигов - т.е. я получаю производительность с её latency, но какой жопой оно так?

Потом я вспомнил, что гцц гинерит анрольный код вида:

add $1, %reg0
add $1, %reg0
//а не
add $1, %reg0
add $1, %reg1

Т.е. на неё вообще не работает переименовывание регистров - и инструкции постоянно в локе. Я это проверил и оказался прав. Ну и я написал такой мемадд:


__v8sf fmaadd(__v8sf a, __v8sf b) {
  return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);
}

inline void fma_10way_finality(__v8sf * cache, __v8sf * it, __v8sf * end) {
  switch(end - it) {
    case 8:
      *(cache + 7) = fmaadd(*(cache + 7), *(it + 7));
      *(cache + 6) = fmaadd(*(cache + 6), *(it + 6));
    case 6:
      *(cache + 5) = fmaadd(*(cache + 5), *(it + 5));
      *(cache + 4) = fmaadd(*(cache + 4), *(it + 4));
    case 4:
      *(cache + 3) = fmaadd(*(cache + 3), *(it + 3));
      *(cache + 2) = fmaadd(*(cache + 2), *(it + 2));
    case 2:
      *(cache + 1) = fmaadd(*(cache + 1), *(it + 1));
      *(cache + 0) = fmaadd(*(cache + 0), *(it + 0));
    case 0:
      break;
    default: error_at_line(-1, 0, __FILE__, __LINE__, "bad_aligned");
  }
}

double memaddfma_10way(buf_t buf) {
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = (__v8sf){};
  __v8sf * cache = (__v8sf[10]){{}};
  uint64_t i = 0;
  while((it += 10) <= end) {
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    i = 0;
  }
  fma_10way_finality(cache, (it - 10), end);
  summ = (*(cache + 0) + *(cache + 1) + *(cache + 2) + *(cache + 3) +
	  *(cache + 4) + *(cache + 5) + *(cache + 6) + *(cache + 7) +
	  *(cache + 8) + *(cache + 9));
  return hsumf(summ);
}

Пришлось хреначить финалити, ибо тут «анролл» на 10, а почему на 10 - для максимального throughput"а - надо, чтобы каждый каждый регистр юзался через 5тактов - т.е. 10регистров.

И вся эта порятнка нужна для борьбы с тупостью конпелятора.

Это уже: 214.167252GB/s(раельно там в районе 250 - просто мой бенч говно). 107 гигафлопс на ведро. Из теоретических 144, но тут уже влияние кеша. Причем 50+ из которых выкидываются и просто бесплатные.

Теперь вопрос к пацанам - что нам дадут эти гагфлопсы, когда у нас будет массив не 32килобайта, а 32мегабайта? Зачем нужно выживать максимум, когда скорость памяти отсилы 20-30гигабайт и нам хватит даже С++ кода с ffast-math?

Ну и призываются упомянутые мною пацаны: mv - этот тот експерт, что вещал про «руками переименовывать регистры не надо» и «анрол ваще ненужен», emulek вещал про ненужность счёта тактов, и не понимал что такое «беслпатно», AIv - не понимал в чем проблема плюсов, ck114 - так же не понимал в чем проблема плюсов.

Бенчи: https://gist.github.com/superhackkiller1997/606be26fa158ef75501d - вроде я там ничего не напутал.

P.S. - не выпиливайте пж, пусть пацаны «нужно» или «не нужно». Мне интеерсно. Ну и там рекомендации пацанов.



Последнее исправление: beastie (всего исправлений: 1)

Ответ на: комментарий от emulek

на практике часто бывает 100500 чисел 0.0001, и пара чисел 5. У меня получится 20, а у тебя 10. Есть разница?

Сумироватся будет влево - т.е. к 5-ти - это 6знаков максимум в любом порядке сложения.

Даже если мы прибавим 0.0001 к 10-ти - мы непотеряем ниграмма точности даже на флоате. Т.е. ты опать обоссался.

тебе повторить знакопеременный ряд, который даёт ln(2)?

Ты мне приводишь init(там есть функция) в который ты забиваешь свой ряд. Которая инициализирует массив твоеми данными. И мы глядим как ты обосрался.

Carb_blog
() автор топика
Ответ на: комментарий от ddos3

Пройдись по репе любимого дистра и посчитай, сколько там пакетов, которые входят в это «еще чего-то». Если включишь голову и подойдешь к вопросу серьезно, то насчитаешь порядка 99.9%.

оО, ты решил со мной поигать - я уверяю тебя, разница между нашим скиллом настолько колоссальна, что я тебе не советую даже пытаться провернуть такую байду со мною.

И? Много сегодня пишут числодробилок на голом CPU?

Балабол сказал про числодробилки, и теперь внимание:

сколько там пакетов
числодробилок
Пакетов

Обосанно.

Пока что выходит так, что ты тут один д'Артаньян, а все остальные вокруг - сплошные пхписты. Не наводит ни на какие мысли?

По существу есть чё? Я угадал? Либо ты жабит, но скорее какой-то скриптовый ваятель среднего созыва.

Я-то прекрасно знаю, о чем пишу. А вот ты, походу, не совсем. И еще хамишь старшим. Не стыдно так себя вести?

Ещё раз - по уровню развития и уровню скилла ты где-то на уровне моего ногтя, который я отстриг в первые года своей жизни.

Т.е. ты настолько знаешь о чем пишешь, что не осилил загуглить «что такое libc», ну погугли, авось.

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

Т.е. ты обделался, был слит в нулину и «говорить неочем» - эка как эпично. Это прям финалити рожей в говно.

Carb_blog
() автор топика
Ответ на: комментарий от ddos3

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

за последний год у него мозгов вообще не осталось.

emulek
()
Ответ на: комментарий от Carb_blog

Сумироватся будет влево - т.е. к 5-ти - это 6знаков максимум в любом порядке сложения.

эх детка...

.0001*100500
10.0500

а ты говоришь «не будет»...

Ты мне приводишь init(там есть функция) в который ты забиваешь свой ряд. Которая инициализирует массив твоеми данными. И мы глядим как ты обосрался.

ты все мозги пропил? Тебе 1-½+⅓-¼… не посчитать?

emulek
()
Ответ на: комментарий от Carb_blog

Братиша, как скомпилировать-то? Не получается чего-то.

gcc 4.8.2:

-> % gcc-4.8 memad_bench.c -Ofast -march=native -lgomp -fwhole-program -Wall -Wextra -o c_memadd_bench && ./c_memadd_bench
memad_bench.c: In function 'fmaadd':
memad_bench.c:71:3: warning: implicit declaration of function '_mm256_fmadd_ps' [-Wimplicit-function-declaration]
   return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);
   ^
memad_bench.c:71:3: error: incompatible types when returning type 'int' but '__v8sf' was expected
memad_bench.c: In function 'fma_10way_finality':
memad_bench.c:103:5: warning: implicit declaration of function 'error_at_line' [-Wimplicit-function-declaration]
     default: error_at_line(-1, 0, __FILE__, __LINE__, «bad_aligned %llu», end - it);
     ^
memad_bench.c: In function 'fmaadd':
memad_bench.c:72:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
memad_bench.c: In function 'main':
memad_bench.c:163:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

gcc 4.9.0 20140330:

-> % gcc-4.9 memad_bench.c -Ofast -march=native -lgomp -std=gnu99 -fwhole-program -Wall -Wextra -o c_memadd_bench && ./c_memadd_bench
memad_bench.c: In function 'fma_10way_finality':
memad_bench.c:103:5: warning: implicit declaration of function 'error_at_line' [-Wimplicit-function-declaration]
     default: error_at_line(-1, 0, __FILE__, __LINE__, "bad_aligned %llu", end - it);
     ^
In file included from /usr/local/Cellar/gcc49/4.9-20140330/lib/gcc/x86_64-apple-darwin13.1.0/4.9.0/include/immintrin.h:61:0,
                 from /usr/local/Cellar/gcc49/4.9-20140330/lib/gcc/x86_64-apple-darwin13.1.0/4.9.0/include/x86intrin.h:46,
                 from memad_bench.c:9:
memad_bench.c: In function 'fmaadd':
/usr/local/Cellar/gcc49/4.9-20140330/lib/gcc/x86_64-apple-darwin13.1.0/4.9.0/include/fmaintrin.h:63:1: error: inlining failed in call to always_inline '_mm256_fmadd_ps': target specific option mismatch
 _mm256_fmadd_ps (__m256 __A, __m256 __B, __m256 __C)
 ^
memad_bench.c:71:3: error: called from here
   return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);
   ^

l5k
()
Ответ на: комментарий от pulo

читать ведь невозможно

Ещё и жалуется, тебе перепало от мудрости его, а тебе, видите-ли слог не нравится. Смирись, ты просто анскильная лалка, как и все мы тут ((((((

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от Carb_blog

Поиск в помощь, я тебе ещё что-то доказывать должен?

Ага, еще скажи, что ты сам искал, а не брякнул не глядя. Твоя клиническая картина и так тут всем ясна.

Т.е. ты вякнул, а когда тебя спросили «почему?» - ты слился?

Я слился? Да ты сам в этом топике кастанул тех, кто тебя мордой в говно окунали. Только суть не изменилась и весь твой тред - не более, чем «бульк» его поверхности. Ты свего лишь осилил одну сраную оптимизацию под _1_ компилятор под _1_ архитектуру. И я молчу про наличие IPP, которая делает твой высер просто ненужным.

Радуйся, что я тебе не занулю - тут всё будет культурно.

ЩИТО есть «занулю»? Электрик штоле?

Модераторы, вот как с такими говорить «культурно»? Т.е. он клевещит, обзывается, сливается на раз-два, а мне даже слова плохого сказать нельзя?

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

Pavval ★★★★★
()
Ответ на: комментарий от emulek

.0001*100500

И? Стало больше 6-ти знаков?

а ты говоришь «не будет»...

Чего не будет?

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

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

Какой бы ты жопой не складывал свои 0.0001, если ты потом их прибавишь к 1.e7 - ты получишь жопу везде, кроме того, что влезет до e0, а тоже самое ты получишь просто складывая изначально числа в любом порядке.

Чтобы твоя байда реально работала - тебе надо переходы по 2-3порядка между числами, а посчитай сколько это надо чисел.

Давай ещё раз. У тебя есть 5.e0, пока оно не растёт влево - его точность до e-6, а твоё 1.e-4 входит в его «точность».

Давай возмём 1.e4 - его точность до 1.e-3 - т.е. если ты будешь складывать твоё число с ним - ты получишь жопу, ибо его значение за «точностью» 1.e4.

Поэтому ты можешь сложить 100 чисел 1.e-3 -ты получишь значение в районе e-1, которое уже входит в точность числа e4. Если же ты будешь складывать не 10, а 7чисел - ты получишь жопу и они уйдут в ноль.

Для этого проще заюзать дабл. Я надеюсь секта крута не высосала из тебя мозг окончательно.

ты все мозги пропил? Тебе 1-½+⅓-¼… не посчитать?

Ну дак посчитай. Напиши инит. Я за тебя посчитаю.

Carb_blog
() автор топика
Ответ на: комментарий от Pavval

Ага, еще скажи, что ты сам искал, а не брякнул не глядя. Твоя клиническая картина и так тут всем ясна.

Ага, ещё скажи, что ты сам что-то искал, а не брякнул не глядя.

Ага, пациенты палате n6 считают друг друга «здоровыми».

Я слился? Да ты сам в этом топике кастанул тех, кто тебя мордой в говно окунали.

Вообще-то очередной пхпист рассказывает кто кого окунул. Ну дак ты мне покажешь где кто кого окунул? Или ты «брякнул не глядя»?

Ты свего лишь осилил одну сраную оптимизацию

Вообще-то их тут 10050.

под _1_ компилятор

О5 ты кукарекаешь нихрена не понимая, под какой-такой «конпелятор»? Где там юзается что-то от конпелятора? Ты же мне покажешь?

под _1_ архитектуру.

Вообще-то это общее для всех архитектур, под одну архитектуру там только add, который работает в 2раза быстрее дефолтного. О5 пробалаболился.

И я молчу про наличие IPP, которая делает твой высер просто ненужным.

Как так не нужным? Ты прочитал в треде про IPP - молодец, теперь погугли что это. И как так не нужным, в чем ненужный?

ЩИТО есть «занулю»? Электрик штоле?

Да, кукарекатинг вземлю спущу. Загоню в говно всего под ноль.

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

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

Т.е. подожди, абсалютно необразованный, невежественный балабол-пхпист, который НИЧЕГО нужного не сделал в своей жизни, бесполезный кусок курлыкающего коечего рассказывает мне что-то? А ну ок.

Carb_blog
() автор топика
Ответ на: комментарий от l5k

У тебя в каменье fma хоть есть? Оно у тебя не нашло _mm256_fmadd_ps() - значит нема.

cat /proc/cpuinfo  | grep -o fma

Хотя у тебя гейОС - я хз есть там /proc/cpuinfo - погугли.

Carb_blog
() автор топика
Ответ на: комментарий от ii343hbka
$lscpu
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K

Да, «половина» l1 юзается под кеш инструкций, а вторая половина как общий кеш.

Carb_blog
() автор топика

Самое смешное в том, что пацанам настолько нечего сказать, что они пытаются рассказать мне как же неточен мой код, причем пацанам покласть что любой код не точен абсалютно так же, а своей «сортеровкой» емулек еле-еле снимет 200метров/с, хотя проще заюзать дабл. Но мы не будем на него обижаться - он слишком нулёвый.

Пацаны кукарекают про ipp, которая интелонлипроприетарщина, да и которая бесполезна, причем об ipp они ничего не знают.

Пацаны кукарекают, что ipp «быстрее», хотя этого просто не может быть по определению. Мы не будем обижатся на пацанов - они слишком нулёвые.

В следующем посте я расскажу для чего нужен этот код, и как на его основе строится всё в этом мире.

Но вы всёже попытайтесь ответить на вопрос - зачем нужен код, который выдаёт 250гигов, когда скорость памяти отсилы 20-30 на ведро? Это очень просто.

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

И? Стало больше 6-ти знаков?

стало намного меньше 23х битов. А про свои «знаки» забудь.

Чтобы твоя байда реально работала - тебе надо переходы по 2-3порядка между числами, а посчитай сколько это надо чисел.

переход «1 порядок» это вдвое. «2-3 порядка» это в 4..8 раз.

А у тебя 32765, это 15 порядков.

Т.е. если у тебя порядок был равен 100, то после твоей операции над одинаковыми числами, у тебя будет 115. Уяснил?

Вот тебе беньч, чтоб ты осознал бездну своей анскильности:

1. берёшь равномерный ГПСЧ, который даёт uint32_t, число 0..4294967295

2. забиваешь свой массив float'ов этим ГПСЧ, тупо побитно копируя uint32_t в float

3. Копируешь 32К float'ов в 32К double

4. складываешь отдельно float, и отдельно double

5. сравниваешь результат.

ты все мозги пропил? Тебе 1-½+⅓-¼… не посчитать?

Ну дак посчитай. Напиши инит. Я за тебя посчитаю.

твоего суперскилла не хватает для того, что-бы сгенерить последовательность 1, -½, ⅓, -¼, ⅕… ?

emulek
()
Ответ на: комментарий от Carb_blog

хотя проще заюзать дабл.

это ничего не меняет. Проблема носит качественный, а не количественный характер. Вот если-бы у тебя было 3 операции, то замена на double помогла(в большинстве случаев, но не всегда). Но у тебя не 3, а 32768.

а своей «сортеровкой» емулек еле-еле снимет 200метров/с

детка, это не я придумал. Все так делают, ибо иначе, «результатом» можно только подтереться. И делают так вовсе не после распространения SIMD, а ещё с тех пор, когда тебя в проекте не было.

emulek
()

ко-ко-ко царь в курятнике

Ко-кок. У нас все куры побросали своих петухов и желают нестись только от царя. Ко-кок! Хотят тебя к себе в курятник, чтобы ты показал им скилл и прочел лекцию. Бак-бак-кудах! БЕЗ ЭТОГО НЕТ ЯИЦ!

esandmann
()
Ответ на: комментарий от emulek

стало намного меньше 23х битов. А про свои «знаки» забудь.

Чего? Какие биты, а вот мне интересно 0 - это тоже 23бита? А 1? Это 23бита?

переход «1 порядок» это вдвое. «2-3 порядка» это в 4..8 раз.

Чего? Ты упоролся? Во флоате десятичный порядок, а не двоичный. Двоичный порядок есть только у двоичного представления мантисы.

Т.е. если у тебя порядок был равен 100, то после твоей операции над одинаковыми числами, у тебя будет 115. Уяснил?

Чиго? Ты вообще представляешь себе, балаболка, как работает флоат? Хотя что с тебя спрашивать. Чего поряд, какими числами, какими опарациями?

1. берёшь равномерный ГПСЧ, который даёт uint32_t, число 0..4294967295

и?

2. забиваешь свой массив float'ов этим ГПСЧ, тупо побитно копируя uint32_t в float

Зачем? Угу, я конечно не буду тебе говорить об inf.

3. Копируешь 32К float'ов в 32К double

Зачем?

4. складываешь отдельно float, и отдельно double

Зачем?

5. сравниваешь результат.

Зачем?

Т.е. ты конкретно сказать нихрена не можешь, я правильно понял? Ты обосрался, я правильно понял?

твоего суперскилла не хватает для того, что-бы сгенерить последовательность 1, -½, ⅓, -¼, ⅕… ?

Твоего скилла не хватает, чтобы сгенерить последовательность?

Carb_blog
() автор топика
Ответ на: комментарий от emulek

это ничего не меняет. Проблема носит качественный, а не количественный характер. Вот если-бы у тебя было 3 операции, то замена на double помогла(в большинстве случаев, но не всегда). Но у тебя не 3, а 32768.

Как же меня одалела твоя тупость. 0.0001 мы складываем 100500раз, по сортировочки, а потом добалвяем 1.e7f и вуаля - твоя «техника поомгла».

Ещё раз тебе, нулёвому ламерюге поясняю - твоя байда не работает. Дабл даст расширение порядка благодаря которому не уплывёт точность. За этот порядок точность уплывёт в любом случае.

Ещё раз, когда ты складываешь числа - порядок должен расширятся до их суммы. Т.е. чтобы сложить весь дипазон флоатов - тебе надо 60порядков, а не 6, как сейчас.

В любом случае точность у тебя будет отсилы 10%, и этим результатом ты можешь только подтерется.

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

Т.е. число 0.0001 -4-й порядок и число 0.001 -3-й, если ты будешь складывать больше 10ти(в данном случае) чисел с -4-м порядком - ты получишь 0.001 - т.е. -3-й порядок.

Ты понимаешь, ламерюга, в чем суть того, о чем ты кукарекаешь? Ты понимаешь в каких случаях это работает? Перенос порядка происход только ПРИ ПЕРЕПОЛНЕНИИ предыдущего порядка - это основа.

И это ПЕРЕПОЛНЕНИЕ должно быть В РАЙОНЕ ТОЧНОСТИ СЛЕДУЮЩЕЙ ГРУППЫ, а если оно ВНЕ ТОЧНОСТИ - смысла в твоей байде нет.

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

детка, это не я придумал. Все так делают, ибо иначе, «результатом» можно только подтереться. И делают так вовсе не после распространения SIMD, а ещё с тех пор, когда тебя в проекте не было.

Ещё раз. Скложи мне 1e32 + 1e24 + 1e16 + 1e8 + 1e0 + 1e-8 + 1e-16 + 1e-24 + 1e-32, а я поржу.

Все так делают, ибо иначе, «результатом» можно только подтереться.

Как я люблю, когда нули цепляются за всех. Я потерплю твою нулёвость, атк уж и быть. Вот когда ты складываешь числа e-6 и числа e5, то для полного представления их суммы тебе надо минимум 12порядков + то, что уйдёт влево.

Но сумма будет у тебя самого левого порядка- т.е. e-6 минимум, а остальные 6порядков(e-1 - e-6) у тебя отсекутся. Т.е. у тебя уже будет результат «которым ты можешь подтерется» в любом случае.

И чтобы твоя байда сработала - и «битики» с порядка e-6 дошли до e0(граница точности e5) - тебе надо минимум 1e0/9e-6 чисел - т.е. в районе 100500. Если же у тебя будет на одно число меньше, чем 1e0/9e-6, либо какое-нибудь из чисел будет меньше 9e-6 - тебе даже твоя байда не поможет.

Суть не в том, что кто-то. Суть в том, что ты ламерок даже 200метров не выжмешь, именно ты.

И зачем ты кукарекашь про симды, о которых ты нихренан е знаешь?

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

Пацаны кукарекают про ipp, которая интелонлипроприетарщина, да и которая бесполезна, причем об ipp они ничего не знают.
Пацаны кукарекают, что ipp «быстрее», хотя этого просто не может быть по определению. Мы не будем обижатся на пацанов - они слишком нулёвые.

Так ты сравнение-то произвел? Я результатов не видел просто. Интересно, что покажут обе реализации на массиве в, скажем, 40 МБ.

yoghurt ★★★★★
()
Ответ на: комментарий от Carb_blog

а вот мне интересно 0 - это тоже 23бита? А 1? Это 23бита?

да, детка, для float — да.

Чего? Ты упоролся? Во флоате десятичный порядок, а не двоичный. Двоичный порядок есть только у двоичного представления мантисы.

идиот. Ну не позорься ты так...

Угу, я конечно не буду тебе говорить об inf.

мало вероятно, что у тебя попадётся inf.

3. Копируешь 32К float'ов в 32К double

Зачем?

для проверки.

5. сравниваешь результат.

Зачем?

что-бы понять, насколько твои фантазии далеко от реального мира.

Твоего скилла не хватает, чтобы сгенерить последовательность?

моего-то хватает, но в этой теме ты — Учитель.

emulek
()
Ответ на: комментарий от yoghurt

Ты хоть не будь таким, как эти бомжи. Любая из этих функций упрётся в память и будет выдавать одно и тоже. В чем смысл сравнивать?

Ты лучше подумай и скажи мне - зачем нужны такая функция, которая выдаёт 250гигов, когда память выдаёт 21гиг? Это основная суть поста.

sphk_summ_fast: 40960KB: 21.036949GB/s
ipp_summ_fast:  40960KB: 20.965905GB/s

Этот разброс - это погрешность.

Те опущенные лишь пытаются кукарекать и пытаться показать себя «непонятой илитой» в глазах пхпистов, курлыкая где-то в районе днища.

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

зачем нужны такая функция, которая выдаёт 250гигов, когда память выдаёт 21гиг?

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

yoghurt ★★★★★
()
Ответ на: комментарий от Carb_blog

Во флоате десятичный порядок, а не двоичный.

facepalm.jpg

Вы после этого еще продолжите с ним о чем-то разговаривать?

anonymous
()
Ответ на: комментарий от emulek

да, детка, для float — да.

Нет.

идиот. Ну не позорься ты так...

Как?

мало вероятно, что у тебя попадётся inf.

инфа сотка.

для проверки.

Чего проверки?

что-бы понять, насколько твои фантазии далеко от реального мира.

Т.е. ты даже объяснить ен можешь в чем заключаются мои фантазии, и в чем заключается реальный мир?

моего-то хватает, но в этой теме ты — Учитель.

Сомневаюсь, тыж начал кукарекать «не точно, а надо воттак» - дак показывай, что так, как надо тебе - правильно.

Ты же кукарекнул, что «всё нетак», а когда тебя спросили - «что нетак» - ты начал кукарекать «всетакделают, ко-ко-ко, иди проверь, ко-ко-ко».

Carb_blog
() автор топика
Ответ на: комментарий от yoghurt

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

Чиго? Какая порция, каких данных. Чтобы тебе прочитать эту «порцию» из кеша, тебе надо для начала её прочитать из оперативки, которая выдаёт 21гиг. Это не имеет смысла. Думай дальше.

Там-то имеет смысл

Где там?

Carb_blog
() автор топика
Ответ на: комментарий от anonymous

Вы после этого еще продолжите с ним о чем-то разговаривать?

В чем фейспалм? Не согласен - иди затести, да и вообще какого хрена я должен с вами разговаривать, когда ты несёшь фигню, а миня в этом обвиняешь. И твои братюни по разуму.

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

мало вероятно, что у тебя попадётся inf.

инфа сотка.

проверяй, раз боишься.

для проверки.

Чего проверки?

точности. Точнее её отсутствия.

Т.е. ты даже объяснить ен можешь в чем заключаются мои фантазии, и в чем заключается реальный мир?

ещё раз для тупых: ошибка в твоих вычислениях ОЧЕНЬ велика. Настолько, что она делает бесполезными все эти твои вычисления.

Если уж тебе хочется продемонстрировать свои скиллы, то используй нормальный _алгоритм_, ссылку уже дали, но я повторю для тупых: http://ru.wikipedia.org/wiki/Алгоритм_Кэхэна

Учти, что это НЕ единственный способ, и для многих практических случаев он не годен. Но хоть его реализуй. А просто так свалить все float'ы в кучу может любой мудак(но только ты не постеснялся это сделать прилюдно).

Сомневаюсь, тыж начал кукарекать «не точно, а надо воттак» - дак показывай, что так, как надо тебе - правильно.

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

emulek
()
Ответ на: комментарий от Carb_blog

Да, гейОС. Сейчас поищу, спасибо, оставайся в теме, не уходи.

l5k
()
Ответ на: комментарий от Carb_blog

Дык. В реальной жизни обычно не ограничиваются каким-то одним вызовом, их целый конвеер. И этот конвеер ессно оптимальнее гонять на данных, помещенных в кэш.

yoghurt ★★★★★
()
Ответ на: комментарий от Carb_blog

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

Во вторых: если числа могут быть отрицательными, то порядок результата их сложения может быть сильно меньше порядка самых больших данных, а значит расхождения от порядка сложения могут быть гораздо существеннее.

Но это «таблица умножения». Если кто-то собирается оперировать данными, разрядность которых еле-еле влазит в выбранный формат (в мантиссу), и ничего не предпринимает для контроля порядка оперирования этими числами (и если ему важна точность) - он ССЗБ.

Для «нормализованных» данных программа работает? Работает. Для ненормализованных данных ни один «простейший» вариант не годится, но любой может быть использован «внутри» расширенного алгоритма. Универсальный способ сложения набора «флоатов» с максимальной точностью только один - расширение мантиссы. Но к обсуждаемой задаче это не относится :)

yyk ★★★★★
()
Ответ на: комментарий от Carb_blog

В чем фейспалм?

В том, что о программировании пытается рассуждать необразованное днище, считающее, что у флоата двоичный порядок.

anonymous
()
Ответ на: комментарий от Carb_blog

эээ....многоканальный режим? Так что такое бесплатные вычисления? И где нужно складывать массив флоатов IRL?

Erfinder
()
Ответ на: комментарий от yyk

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

Я описал в какик случаях порядок будет влиять. Ты хоть мильярды чисел 1e-20 складывай - прибавя к ним 1e6 - ты потеряешь всё то, что ты там складывал. Сортировка должна тебе дать цепочку, благодаря которой разряды не будут отсекаются, а будут иметь возможность на то, что их сумма перетечёт в следующий разрят, и уже не будет обрезанна.

Это суть метода, и у меня бомбит только от того, что ламерок пытается частный случай назвать «еднственно верным», хотя его случай так же фейлится.

Во вторых: если числа могут быть отрицательными, то порядок результата их сложения может быть сильно меньше порядка самых больших данных, а значит расхождения от порядка сложения могут быть гораздо существеннее.

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

Но это «таблица умножения». Если кто-то собирается оперировать данными, разрядность которых еле-еле влазит в выбранный формат (в мантиссу), и ничего не предпринимает для контроля порядка оперирования этими числами (и если ему важна точность) - он ССЗБ.

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

Для «нормализованных» данных программа работает? Работает. Для ненормализованных данных ни один «простейший» вариант не годится, но любой может быть использован «внутри» расширенного алгоритма.

Мне похрен что там работает - сложение флоатов - это пример, и мне покласть работает он или нет. Придирка к точности - это единственное оправдание, которое ламерки типа емулеки юзают воимя оправдания своей анскильности и возможности покукарекать и меня в чем-то уличить.

Изначально это вообще был мемадд - складывание 2-х массивов, но я посчитал это слишком сложным для эмулеков, ибо там надо пилить в вариации кеш/рама.

Carb_blog
() автор топика
Ответ на: комментарий от Erfinder

эээ....многоканальный режим?

Что-то вразумительное скажешь?

Так что такое бесплатные вычисления?

Ну как тебе объяснить - недано понять - это болезнь, ламеризм и пхп говновно мозга.

И где нужно складывать массив флоатов IRL?

А причем тут массив флоатов?

Как эти вылезщие со днища ламерки меня одалели, ты решил за емулеками повторять? Своей бошки на плечах нет? Я рад, что ты прочитал комменты, но мне пичально, что ты ничего не понимаешь. Прогуляйся и перечитай, без попыток ослить и что-то из себя строить.

Carb_blog
() автор топика
Ответ на: комментарий от anonymous

В том, что о программировании пытается рассуждать необразованное днище, считающее, что у флоата двоичный порядок.

Обо мне пытается рассуждать необразованное днище - это так мило. Мне вот интересно, почему кому-то можно нести херню, а мне нельзя?

Вот ты - нулина пхпешная, а пытаешься мне что-то сказать? Ты хочешь со мною поспорить, посорвеноваться? Яж тебя с говном смешаю. И ты даже этого не пытаешься, как и твои братья по разуму.

В чем заключается твоя образованность? В том, что ты осилил википедию прочитать? Мололец, а ещё?

Carb_blog
() автор топика
Ответ на: комментарий от no-such-file

Ну дак он там кукарекал «всегда работает» - должно работать - инфа соточка.

Иди перечитай своего дружка-питушка, не он ли кукарекал «только так, иначе подтерется»?

Можешь там не по одному числу складывать, авось памяти хватит и тебе «всегдаработает» даст профит.

Что ты там со своей фпгашкой? Досихпор веришь, что в 1000раз быстрее x86? Тебе же инстересно, давай следующий бложик сделаем про твои считалочки? Проверим х86, а?

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

Вот ты - нулина пхпешная, а пытаешься мне что-то сказать? Ты хочешь со мною поспорить, посорвеноваться?

Ты пока не заслужил, чтобы я с тобой спорил и соревновался.

В чем заключается твоя образованность? В том, что ты осилил википедию прочитать?

Мы сейчас говорим не обо мне, а о тебе. Твоя НЕобразованность заключается в том, что ты не способен осилить даже статью в википедии.

anonymous
()
Ответ на: комментарий от Carb_blog

Все мои вопросы, не троллинг, я и вправду не знаю.

Что-то вразумительное скажешь?


Так да или нет?

Ну как тебе объяснить - недано понять - это болезнь, ламеризм и пхп говновно мозга.


Так ты объясни, а я решу могу ли я понять.

А причем тут массив флоатов?


Начнём с простого - сумма елементов(float) массива. Как написать её быстро?


Как эти вылезщие со днища ламерки меня одалели, ты решил за емулеками повторять? Своей бошки на плечах нет? Я рад, что ты прочитал комменты, но мне пичально, что ты ничего не понимаешь. Прогуляйся и перечитай, без попыток ослить и что-то из себя строить.


Я из себя не строю. Я просто хочу понять. И ради этого задаю вопросы.

Erfinder
()
Ответ на: комментарий от Carb_blog

Что ты там со своей фпгашкой?

А? Ты меня с mv перепутал.

Ну дак он там кукарекал «всегда работает» - должно работать - инфа соточка.

А кто сказал, что переполнение - это «не работает»? Документированное поведение для float - всё работает как задумано.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Ты пока не заслужил, чтобы я с тобой спорил и соревновался.

Нет, нет. Так не бывает.

Мы сейчас говорим не обо мне, а о тебе.

Ой как ты поплыл, как поплыл. Понимаешь, когда школьник подходит к дяде и говорит «ты днище необразованное» - дядя ему отвечает, а ты собственно кто такой, чтобы кукарекать мне об образованности, дак вот - ты кто такой, чтобы мне кукарекать об образованнности? В чем твоя образованность заключается, где она7

заключается в том, что ты не способен осилить даже статью в википедии.

Емулек её так же не осилил, да и вообще - что хочу, то и говорю.

Carb_blog
() автор топика
Ответ на: комментарий от Erfinder

Все мои вопросы, не троллинг, я и вправду не знаю.

А ну ок.

Так да или нет?

Нет, понимаешь в чем штука - мы считаем на одном ведре. Если ты про память, то да - одно ведро неможет снять весь throughput даже с 2-х каналов, но суть в том, что кол-во вёдер у нас тоже увеличивается. И будет на 4-х ведрах не 250гигов, а терабайт.

Так ты объясни, а я решу могу ли я понять.

Это же так просто. Вот у тебя одно сложение, когда одна функция выдаёт 100гигов, а вторая 200. Когда у тебя будет 2сложения - одна функция будет выдавать 50гигов, а вторая 100, когда 4сложения - одна 25, а вторая 50. Когда у тебя будет 4сложения - у тебя будет 12.5гигов на первой, а 25гигов на второй.

Я из себя не строю. Я просто хочу понять. И ради этого задаю вопросы.

О5 эти ирл, о5 эти зачем. Вот ты гуглишь «рекурсия», а тебе показывают обосанный факториал, ты же не говоришь «зачем мне факториал? Кому нахрен он нужен» - нет, это пример.

Пример должен отражать всю суть, чтобы не размазать суть по сложности и избыточности самого примера.

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

Флоаты там по причине fma, как показательный пример. Я мог бы написать скаллирование, сложение массивов, либо ещё чего, но это требует запись - а запись это совершенно разные реализации для кеша/памяти. Но один хрен ничего не поменяется.

Carb_blog
() автор топика
Ответ на: комментарий от Carb_blog

й как ты поплыл, как поплыл. Понимаешь, когда школьник подходит к дяде и говорит «ты днище необразованное» - дядя ему отвечает, а ты собственно кто такой, чтобы кукарекать мне об образованности, дак вот - ты кто такой, чтобы мне кукарекать об образованнности? В чем твоя образованность заключается, где она7

Еще раз - моя образованность совершенно неважна. Речь идет о твой НЕобразованности. Ты ее всем продемонстрировал своим кукареканьем о порядке флоата.

От моей образованности никак не зависит тот факт, что ты сморозил полнейшую хуйню.

anonymous
()
Ответ на: комментарий от no-such-file

А? Ты меня с mv перепутал.

А не ты ли лабу писал на фпгашке? Ты точно со мною спорил про обходы/локальность в теме alv, авот про лабу на фпгашке я не уверен.

А кто сказал, что переполнение - это «не работает»? Документированное поведение для float - всё работает как задумано.

Оно так же работает и в моём примере, но емулеку о но не работает по причине того, что результатом можно подтретеся. Вот тут тоже не работает, ибо результатом можно подтерется.

Carb_blog
() автор топика
Ответ на: комментарий от anonymous

От моей образованности никак не зависит тот факт, что ты сморозил полнейшую хуйню.

Не зависит, а вот моя образованность зависит. Зачем ты плывёшь?

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

И да, ты там почитай контекст там говорится совершенно про другой порядок - порядок числа, а не порядок мантиссы. Ты молодец, что первую страничку википедии почитал про устройство формата, только вот мы не про устройство формата. Да и вообще ты меня одалел своим трёпом.

Да и с какого мне нельзя нести херню? Хочу и несу. Пронёс - успокойся и скажи что-то посуществу, ты вроде не тотальное днище, а дахе попахивает вменяемостью.

Carb_blog
() автор топика

Вообще у камня есть такая фича, допустим у нас:

add $1, %reg0 //вот тут инструкция add залочит регистр reg0
add $1, %reg0 //а эта инструкция уйдёт в лок до особождения предыдущей инструкцией регистра reg0
Чтобы такой жопы небыло - есть специальная фича:
add $1, %reg0 //lock reg0
add $1, %reg0 //И тут вместо того, чтобы уйти в лок - камень вместо reg0 даёт инструкции любой свободный регистр.

Я тут почитал 9ю страницу http://www.agner.org/optimize/microarchitecture.pdf . Правильно ли я понял, что CPU сам понимает, что надо регистры переименовать, т.е. без помощи компилятора?

P.S. Я так понимаю, что Вы доказали, что можно (обмазавшись интринсками) руками написать более эффективный код, чем генерит компилятор? Это вроде как известный факт. Можете как-нибудь ещё раз подытожить для медленно соображающих?

P.P.S. Не обижайтесь, но орфографические ошибки вызывают некоторые сложности с восприниманием текста. Было бы круто, если можно с этим что-нибудь сделать.

Kakadu
()
Ответ на: комментарий от Carb_blog

Оно так же работает и в моём примере

Но на твоём примере не работают другие случаи. Просуммируй 1.234567 32к раз. Только не надо говорить, что суммировать тут не нужно, а можно просто умножить - тест есть тест.

Ты точно со мною спорил про обходы/локальность в теме alv

Да, было дело. Ты там упарывался и доказывал, что вычисления на пуле коротких массивов (типа такой список, но «анроллнутый») быстрее, чем на просто монолитном массиве. Странно, что в этой теме я не вижу никаких пулов и списков.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.