Russian Qt Forum
Ноябрь 15, 2024, 08:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 4 5 [6] 7 8   Вниз
  Печать  
Автор Тема: Итераторы  (Прочитано 47263 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #75 : Апрель 17, 2013, 19:18 »

А вот Ваше предложение использовать др контейнер (напр список) от жизни далековато.
Почему? Вовсе нет. Он на таком же расстоянии как и ваш.

Я Вам уже говорил что расход памяти резко возрастает, никакой реакции (впрочем не удивлен, это типично для теоретиков).
Да вы что? Но меня это совершенно не пугает по моим требованиям нам нужна скорость при управлении точками, память вторична.
Это сложно понять парню, который знает только индексы. У него все в это упирается.

Более того - как Вы подадите список в OpenGL? Там нужны линейные данные.
Ни каких OpenGL, только Software render, только хардкор.

Так ведь др проблемы - напр как сериализовать/десериализовать?
У вас и с этим проблемы? Сожалею.

Хотите здесь показать подход std/stl - пожалуйста, как я уже говорил - не возражаю.
Я никому ничего доказывать не собирался, это вы создали тему, что бы нас всех поразить своим кодом. Но, в который раз, не вышло.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #76 : Апрель 17, 2013, 19:37 »

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

Забыл ответить. Не в это, т.к. операция *(array + i) при использовании оптимизации уровня O2 проходит за одну команду ассемблера, в отличие от того, что ты написал:

Код
C++ (Qt)
a[i] = 44;
 

Код
ASM
movl $44, 4(%esp)
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #77 : Апрель 17, 2013, 20:06 »

Забыл ответить. Не в это, т.к. операция *(array + i) при использовании оптимизации уровня O2 проходит за одну команду ассемблера, в отличие от того, что ты написал:
Код
ASM
movl $44, 4(%esp)
 
Это он хорошо оптимизировал. Улыбающийся
Он простые примеры может и в
Код:
xor eax, eax
ret
компилировать. Улыбающийся

А вот если ты цикл добавишь, то увидишь:
Код:
movl    %eax, (%esp,%eax,4)
хоть с vec, хоть *(vec+i).
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #78 : Апрель 17, 2013, 20:21 »

хоть с vec, хоть *(vec+i).

Разницы между первым и вторым нет, я же сразу написал. Речь шла о том, что доступ по индексу - это не та сложная конструкция, что ты написал. При должном уровне оптимизации она разворачивается в одну команду, даже в цикле (gcc 4.7):

Код
ASM
L2:
movl %ebx, 4(%esp) ; array[i] = i
addl $1, %ebx      ; i++
movl $LC0, (%esp)
call _printf       ; printf("%d\n", i)
cmpl $10, %ebx     ; i < 10
jne L2
 
« Последнее редактирование: Апрель 17, 2013, 20:23 от Alex Custov » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #79 : Апрель 17, 2013, 20:51 »

Разницы между первым и вторым нет, я же сразу написал. Речь шла о том, что доступ по индексу - это не та сложная конструкция, что ты написал. При должном уровне оптимизации она разворачивается в одну команду, даже в цикле (gcc 4.7):
Усложни пример.
У меня gcc 4.8, я привел ассемблерную команду, которая делает то, что я написал.

И это сишные массивы, а с коллекциями все похуже. Попробуй с оператором [].
« Последнее редактирование: Апрель 17, 2013, 20:53 от Old » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #80 : Апрель 18, 2013, 08:36 »

Где с 2000 года не брал в руки шашку работал с OpenGL. Поэтому, про дисплейные списки решил не писать, а посмотреть, что там нового придумали...
Посмотрел.

Более того - как Вы подадите список в OpenGL? Там нужны линейные данные.
Это кто вам такое сказал? Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #81 : Апрель 18, 2013, 16:47 »

Я никому ничего доказывать не собирался,
А тогда чему посвящены Ваши многочисленные посты в этой теме? Улыбающийся Показать что Вы непререкаемый авторитет в машинном коде? Ну тогда Вы тем более должны понимать что программисту-практику очень редко нужно подсчитывать такты и вообще совать хобот в машинный код. Ему важно оценить выигрыш от возможной переделки кода - а он здесь, как ни крути, ничтожен. Чего же толочь воду в ступе?  Улыбающийся

это вы создали тему, что бы нас всех поразить своим кодом. Но, в который раз, не вышло.
Почему "поразить"? Как Вы замечали, я пишу несколько старомодно, вот мне было интересно как ту же задачу будут решать молодые, продвинутые и/или очень знающие. А вдруг я занимаюсь "изобретением велосипеда"? (что вполне возможно). Что же Вам не нравится? Что решения Вы не показали? Ну так моей вины в этом нет, я ж Вам не мешал. И ни к чему советовать мне заменить эту задачу другой - она не то что надо обходить.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #82 : Апрель 18, 2013, 16:52 »

вот мне было интересно как ту же задачу будут решать молодые, продвинутые и/или очень знающие.
Это придумки. Подмигивающий
Итераторы - настолько примитивная вещь, что любой желающий понимает где они выгодны, а где нет просто прочитав 1 главу своей библию 10-летней давности (итераторы в несколько раз старше этой книги). Улыбающийся

А вот это действительно важно. Становиться понятно почему везде векторы и индексы.
Ответьте если не сложно:
Цитировать
Более того - как Вы подадите список в OpenGL? Там нужны линейные данные.
Это кто вам такое сказал? Улыбающийся

И куда именно вы подаете данные в OpenGL?
« Последнее редактирование: Апрель 18, 2013, 16:55 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #83 : Апрель 19, 2013, 07:03 »

И куда именно вы подаете данные в OpenGL?
Я использую в основном glVertexPointer, в отдельных случаях glDrawArrays

А вот это действительно важно. Становиться понятно почему везде векторы и индексы.
Типа "А почему бы не использовать др контейнеры/структуры данных? Тогда удаление может быть быстрее и легче". Ну так Вы же понимаете что этот выбор определяется очень многими причинами и удобство удаления - только один из резонов (возможно десятый или двадцатый по важности). Подобные предложения "изменить архитектуру приложения" в угоду частной задаче выглядят весьма легковесно (этим часто грешит m_ax  Улыбающийся)
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #84 : Апрель 19, 2013, 07:40 »

Ну так Вы же понимаете что этот выбор определяется очень многими причинами и удобство удаления - только один из резонов (возможно десятый или двадцатый по важности).
Ну я вам еще подскажу одно "удобство" - это скорость добавления (это наверное тридцатый по важности момент).
Что же мы имеем: у нас появилась скорость при добавлении и скорость при удалении.
Хотелось бы узнать остальные (теперь уже важные) причины выбора вектора. Если они конечно есть. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #85 : Апрель 20, 2013, 09:11 »

Ну я вам еще подскажу одно "удобство" - это скорость добавления (это наверное тридцатый по важности момент).
Что же мы имеем: у нас появилась скорость при добавлении и скорость при удалении.
Хотелось бы узнать остальные (теперь уже важные) причины выбора вектора. Если они конечно есть. Улыбающийся
Я Вам отвечал на это по меньшей мере трижды, больше не буду. Эффект "плохая задача". Утверждается что лучше вообще делать не так, долгие (и совершенно бесполезные) выяснения причин и.т.д. А в действительности задача "плоха" только тем что в 1 строчку решения нет, надо чуть-чуть подумать. И это частенько не нравится - как же так, с нашим отличным владением "auto" и др - все должно решаться  с пол-пинка. Вот и флудим - то о тактах, то о хранении адресов, то еще о чем - думать-то лень  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #86 : Апрель 20, 2013, 09:30 »

Я Вам отвечал на это по меньшей мере трижды, больше не буду. Эффект "плохая задача". Утверждается что лучше вообще делать не так, долгие (и совершенно бесполезные) выяснения причин и.т.д. А в действительности задача "плоха" только тем что в 1 строчку решения нет, надо чуть-чуть подумать. И это частенько не нравится - как же так, с нашим отличным владением "auto" и др - все должно решаться  с пол-пинка. Вот и флудим - то о тактах, то о хранении адресов, то еще о чем - думать-то лень  Улыбающийся
Ага, я другого ответа не ожидал. Улыбающийся Реальных то аргументов нет.

Ну тогда я вам расскажу. Вектор (а точнее непрерывный участок памяти) изумительно подходит для хранения статических данных, никаких издержек с памятью не будет. На этом его преимущества и заканчиваются. Как только появляется задача "работу работать" вектор сразу становиться не эффективен и очень затратен, причем по всем показателям: у него наихудшая скорость добавления/удаления элементов + память начинается фрагментироваться (ну вы судя по темам на этом форуме с этим сталкивались не раз Улыбающийся ).
А теперь давайте возьмем реальную модель точек так на 10000 и посчитаем, сколько раз и какой объем данных будет перемещен при добавлении/удалении нескольких точек в вектор (не забудем пересчитать номера индексов в векторе треугольников). И станет ясно, что использовать вектор для этого по меньшей мере глупо. Про партикловые движки и векторы я вообще промолчу, но это наверно сложная тема для вас.

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

А в действительности задача "плоха" только тем что в 1 строчку решения нет, надо чуть-чуть подумать
Камень к себе в огород? Улыбающийся
Вот именно, что там где нужно подумать, вы этого не делаете, а берете "решение" из примеров интернет-курсов "OpenGL за 21 урок", а потом придумываете алгоритмы для героического обхода всех их недостатков и проблем.
« Последнее редактирование: Апрель 20, 2013, 10:08 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #87 : Апрель 20, 2013, 17:01 »

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

В действительности же в подавляющем большинстве случаев 3D модель - весьма стабильная "сущность" и операции удаления/добавления там крайне редки. Ну вот я дам Вам модель чайника, что Вы будете там удалять? Изуродуете чайник - и на этом дело кончится. Добавление - тем более, откуда возьмете геометрию? Ну может в "organic" моделерах (SDS) - там да, все динамично, но это узкая/специфичная область.

Да и вообще - что это за (скажем так, "малодушный") уход от задачи? По-вашему выходит, мол, хранить индексы плохо, давайте этого всячески избегать? Такой подход лишен оснований, наоборот, хранение адресов часто порицается. Так что не надо тут вилять.

Про партикловые движки ...
Напротив, они мне очень интересны, и я предлагал обсудить одну из таких задач, там реально трудная постановка. Впрочем не знаю что Вы имеете ввиду, может разговор о разных движках. 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #88 : Апрель 20, 2013, 17:28 »

В действительности же в подавляющем большинстве случаев 3D модель - весьма стабильная "сущность" и операции удаления/добавления там крайне редки. Ну вот я дам Вам модель чайника, что Вы будете там удалять? Изуродуете чайник - и на этом дело кончится. Добавление - тем более, откуда возьмете геометрию? Ну может в "organic" моделерах (SDS) - там да, все динамично, но это узкая/специфичная область.
Это в вашем мирке они "в подавляющем большинстве случаев" статичны. Улыбающийся Только не понятно, для чего было предлагать написать алгоритм для удаления точки у статической модели?
Давайте мы возьмем поверхность с ландшафтом и будем обстреливать ее снарядами: хочу воронки, разрушение холмов и прочие ямы.

По-вашему выходит, мол, хранить индексы плохо, давайте этого всячески избегать?
Это из чего выходит? Улыбающийся
Я поставил под сомнение обязательное использование векторов для хранения геометрии при использовании OpenGL.
Есть более эффективные контейнеры для работы, например: связанные списки, деки, деки с указателями. И их спокойно можно использовать с OpenGL, но вот только индексы пойдут не со всеми.

Такой подход лишен оснований, наоборот, хранение адресов часто порицается.
Кем порицается, вами? Для меня это не показатель. Подмигивающий

Если у вас есть реальные причины использования вектора - назовите их, иначе давайте закончим эту тему.
Вы только юлите и выкручиваетесь, это становиться скучным.
« Последнее редактирование: Апрель 20, 2013, 19:44 от Old » Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #89 : Апрель 20, 2013, 19:02 »

Наваял решение, критикуйте  Строит глазки
Код
C++ (Qt)
 
 
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <functional>
#include <random>
#include <chrono>
 
template <class T = int>
struct point
{
   typedef T pt;
   point(T x_ = T(), T y_ = T(), T z_ = T()):x(x_),y(y_),z(z_){}
   T x, y, z ;
};
 
typedef point<double> Point3D;
typedef std::array<int,3>    Triangle;
 
std::vector<Point3D>  mPoint;  // котейнер точек
std::vector<Triangle> mTriangle;  // контейнер треугольников
 
#define NUM_POINT (100 * 100000)
#define NUM_TRIA (100 * 100000)
 
int main()
{
   mPoint.resize(NUM_POINT);
   mTriangle.resize(NUM_TRIA);
   std::generate(mPoint.begin(),mPoint.end(),
                 []()->Point3D{static typename Point3D::pt i = 0; i++; return Point3D(i,i,i);});
 
   std::mt19937 gen;
   gen.seed(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
   std::uniform_int_distribution<int> dist(0, NUM_POINT - 1);
   std::generate(mTriangle.begin(),mTriangle.end(),
                 [&]()->Triangle{Triangle res;for(int& i : res) {i = dist(gen);} return res;});
 
   std::vector<int> need_del_point = {2, 12, 24, 37, 42, 55, 69, 75, 84, 93 };
   std::cout<<"Need delete:"<<std::endl;
   for( int i : need_del_point)
       std::cout<<i<<" ";
   std::cout<<std::endl;
 
   std::sort(need_del_point.begin(),need_del_point.end());
 
   auto print_tr = [&](const std::string& msg, size_t cnt)->void
   {
       size_t pnt_cnt = (cnt > mTriangle.size()) ? mTriangle.size() : cnt ;
       if(pnt_cnt)
           std::cout<<msg<<std::endl;
       for(size_t idx = 0; idx < pnt_cnt; ++idx)
           {
               std::cout<<"("<<mTriangle[idx][0]<<","
                             <<mTriangle[idx][1]<<","
                             <<mTriangle[idx][2]<<")";
               if( ((idx+1) % 3) == 0 )
                   std::cout<<std::endl;
               else
                   std::cout<<"\t";
           }
       std::cout<<std::endl;
   };
 
   print_tr("After:", 10);
   auto start_time = std::chrono::high_resolution_clock::now();
   //std::vector<Triangle> tmp_triangle(mTriangle.size());
   struct ModTriangle : public std::binary_function<Triangle,std::vector<int>,Triangle>
   {
       Triangle operator() (const Triangle& t, const std::vector<int>& del_pt)
       {
           Triangle res;
           for(size_t i = 0; i < t.size(); ++i)
               {
                   if(std::binary_search(del_pt.begin(),del_pt.end(),t.at(i)))
                       {
                           res[0] = -1;
                           break;
                       }
                   else
                       {
                           auto it = std::upper_bound(del_pt.begin(),del_pt.end(),t.at(i));
                           res[i] = t.at(i) - std::distance(del_pt.begin(), it);
                       }
 
               }
           return res;
       }
   };
 
   std::transform(mTriangle.begin(),mTriangle.end(),mTriangle.begin(),
                  std::bind(ModTriangle(),std::placeholders::_1,need_del_point));
   auto copy_end = std::copy_if(mTriangle.begin(),mTriangle.end(),mTriangle.begin(),
                                [](const Triangle& t){return (t[0] >= 0);});
   mTriangle.resize(std::distance(mTriangle.begin(), copy_end));
 
   auto copy_pt_end = std::copy_if(mPoint.begin(),mPoint.end(),mPoint.begin(),
           [&](const Point3D& )->bool
          { static int i = 0;
            return (! std::binary_search(need_del_point.begin(), need_del_point.end(), i++));
          });
   mPoint.resize(std::distance(mPoint.begin(),copy_pt_end));
 
   auto end_time = std::chrono::high_resolution_clock::now();
   print_tr("Before:", 10);
   std::cout<<"------------------------------------------------------------------"<<std::endl;
   std::cout<<"deleted points    = "<<NUM_POINT - mPoint.size()<<std::endl;
   std::cout<<"deleted triangles = "<<NUM_TRIA  - mTriangle.size()<<std::endl;
   std::cout<<"test duration : ";
   std::cout << std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count() << ".";
   std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << "s.";
   std::cout<<std::endl;
   return 0;
}
 
Записан
Страниц: 1 ... 4 5 [6] 7 8   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.151 секунд. Запросов: 22.