Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Известно, что обращение к переменной по указателю type* осуществляется в два шага: считывание адреса из указателя, переход по адресу. В то же время ссылка type& содержит прямой адрес на значение переменной в памяти, поэтому обращение по ссылке занимает на один шаг меньше. При выполнении высокопроизводительных операций эта разница ощутима. Возникает вопрос - как динамически изменить адрес ссылки, если заранее неизвестно, где будет расположена связанная со ссылкой переменная. Для наглядности рассмотрим пример: Код: plaintext 1. 2. 3. Аналогичная операция со ссылками: Код: plaintext 1. 2. 3. Возможно, возникнет вопрос - зачем это все нужно. Поясню, в моей задаче есть массив структур, содержащих статические (в смысле не изменяемые) и динамические переменные. Динамические переменные нужно часто обнулять и в некоторые из них загонять новые значения. Делать это нужно много миллионов раз, поэтому было бы выгодно вместо переменных использовать ссылки на элементы массива, который можно эффективно обнулять с помощью memset, а заполнять из кеша с помощью memcopy. Это гораздо быстрее циклического перебора структур с обращением к каждой динамической переменной. Беда в том, что количество структур заранее неизвестно, поэтому неизвестен размер массива, а значит на момент создания структуры нам нечем проинициализировать ссылку и ее придется инициализировать позже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 21:40 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsИзвестно, что обращение к переменной по указателю type* осуществляется в два шага: считывание адреса из указателя, переход по адресу. В то же время ссылка type& содержит прямой адрес на значение переменной в памяти, поэтому обращение по ссылке занимает на один шаг меньше. При выполнении высокопроизводительных операций эта разница ощутима Это не так. На уровне машинного кода реализация указателя и ссылки одинаковая, поэтому никакой разницы в скорости у них нет. (Где вы вообще про такое прочли?) Соответственно, необходимость изменения ссылок надумана. Используйте указатели. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 21:47 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyandreybsИзвестно, что обращение к переменной по указателю type* осуществляется в два шага: считывание адреса из указателя, переход по адресу. В то же время ссылка type& содержит прямой адрес на значение переменной в памяти, поэтому обращение по ссылке занимает на один шаг меньше. При выполнении высокопроизводительных операций эта разница ощутима Это не так. На уровне машинного кода реализация указателя и ссылки одинаковая, поэтому никакой разницы в скорости у них нет. (Где вы вообще про такое прочли?) Соответственно, необходимость изменения ссылок надумана. Используйте указатели. Читал на stackoverflow.com. Эксперименты показывают, что скорость отличается. Возможно, это из-за двойного преобразования. Ведь если есть double& a и double b, то вычислить сумму можно напрямую: a+b, а если есть double* a и double b, то сумма требует на одну операцию больше: *a+b (добавился переход по ссылке *). Разве не так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 22:03 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНа уровне машинного кода реализация указателя и ссылки одинаковая, поэтому никакой разницы в скорости у них нет. Возможно, Вы правы. Я провел еще эксперимент - сравнил скорость работы указателя и ссылки. Разницы не увидел - это может косвенно подтверждать, что реализация на уровне машинного кода одинаковая. Вот что меня действительно удивило - это что доступ по ссылке работает медленнее, чем прямой доступ к переменной. Видимо, ссылка на уровне машинного кода сама реализуется, как переменная с адресом, а не константа. Непонятно только, если это не константа, то зачем было запрещать изменять ее адрес bydesign. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 22:23 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Нет, не так. Как - я выше уже писал: ссылки и указатели- это одно и тоже. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Теперь давайте ссылку на stackoverflow где это написано, и код который показывает отличия в скорости. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 22:28 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsНепонятно только, если это не константа, то зачем было запрещать изменять ее адрес bydesign Потому что на ссылках висят еще и разные семантические правила, которые применяются в compile-time. Если не в даваться в детали, то ссылку нельзя менять по тем же причинам, по которым нельзя поменять адрес объявленной переменной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 22:35 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyЕсли не в даваться в детали, то ссылку нельзя менять по тем же причинам, по которым нельзя поменять адрес объявленной переменной. Чтобы не приводить код к "unsafe" из-за возможных утечек памяти? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.09.2013, 22:45 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Ну не из-за утечек, но да, для безопасности кода. Также как когда мы пишем const int i = 3, то в программе мы менять значение не можем, хотя в машинном коде память доступна для записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 00:00 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, ссылки (если угодно - автоматически разименуемые указатели) дают выигрыш только на больших структурах данных, а вот на "плоских" - нет. Просто потому, что размер этих данных (double, int, etc..) сравним с размером указателя, и тогда что передавать по ссылке, что по значению - всё равно. Для "плоских типов" передавать что-то по ссылке (точно так же, как и по указателю) нужно только в том случае, если "получатель" ссылки должен менять значения, и они должны "отражаться в оригинале" (при передаче по копии такие изменения в "источник" не вернутся). Для больших типов (вроде вектров, списков и т.д) экономия происходит за счёт избегания копирования большого количества элементов контейнера. Вот простой пример: int i = 10; int ii = 1000; int& j =i; cout << i << endl; j = 100; cout << i << endl; j = ii; cout << i << endl; вывод этого кода будет 10 100 1000 А вот переопределить ссылку (чтобы они сначала указывала на одну переменную, а с какого-то места - на другую) - не получится. Но вы можете для себя написать класс-обрёртку, которая будет играть эту роль. Вот только нужно ли? Похоже, что вам надо сначала сформулировать задачу, а уже потом задумываться об эффективности её решения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 10:07 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaА вот переопределить ссылку (чтобы они сначала указывала на одну переменную, а с какого-то места - на другую) - не получится. Но вы можете для себя написать класс-обрёртку, которая будет играть эту роль. Вот только нужно ли? Нужно. В итоге я так и сделал - шаблон class var<T>. Синтаксически с ним можно работать как со ссылкой, но при этом можно менять адрес его указателя. Так динамические переменные заменены с double на указатели vdouble (синоним var<double>). Указатель содержит адрес элемента массива, через который производятся массовые операции изменения значений динамических переменных. Есть только одно неудобство. Например, для double есть операция +=, а для bool ее нет. Поэтому перегрузку оператора += не получается включить в состав класса var<T>. Прочие операции +,-,*,/ и т.п. работают автоматически, т.к. перегружены операторы прямого-обратного преобразования: T& operator=(TT &src) // TT - любой тип будет преобразован к T и извлечено значение в указатель operator T() // возвращается значение типа T& operator TT() // возвращается значение типа T& Но для операции += этого недостаточно. Например, var<double> += double не предусмотрен, нужна перегрузка оператора += для var<T>. Интересно, можно ли это как-то обойти, явно не перегружая операторы ++,--,+=,-= ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 12:32 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsЕсть только одно неудобство. Например, для double есть операция +=, а для bool ее нет. Поэтому перегрузку оператора += не получается включить в состав класса var<T>. А можете продемонстрировать на примере кода, что именно не получается? И кстати, зачем вам обертка для имитации ссылок, если вы можете в любой момент из указателя сделать ссылку? Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 13:25 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Зачем городить какие-то классы вместо указателей, а не пользоваться самими указателями? Кроме этого, умных указателей уже написано достаточно много. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 16:06 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
авторАналогичная операция со ссылками: Код: plaintext 1. 2. 3. Никак. Ссылка -- это константный разименованный указатель. Он НЕ МЕНЯЕТСЯ никогда. Это одно из основных отличий ссылки от указателя. Указатель может указывать на разные объекты в течении своей жизни, ссылка -- не может, после инициализации она указывает всегда на один и тот же объект. авторВозможно, возникнет вопрос - зачем это все нужно. Поясню, в моей задаче есть массив структур, содержащих статические (в смысле не изменяемые) и динамические переменные. Динамические переменные нужно часто обнулять и в некоторые из них загонять новые значения. Делать это нужно много миллионов раз, поэтому было бы выгодно вместо переменных использовать ссылки на элементы массива, который можно эффективно обнулять с помощью memset, а заполнять из кеша с помощью memcopy. Это гораздо быстрее циклического перебора структур с обращением к каждой динамической переменной. Беда в том, что количество структур заранее неизвестно, поэтому неизвестен размер массива, а значит на момент создания структуры нам нечем проинициализировать ссылку и ее придется инициализировать позже. Я мало что понял из этого потока сознания. Используй указатели значит, они ничем не хуже ссылок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 18:06 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyА можете продемонстрировать на примере кода, что именно не получается? Вот класс-обертка: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. Вот пример использования: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Anatoly MoskovskyИ кстати, зачем вам обертка для имитации ссылок, если вы можете в любой момент из указателя сделать ссылку? Просто пока программа не написана полностью, а работа со структурами, члены которых сейчас заменены на такие "указатели" выполняется уже во всех модулях. Поэтому переколбашивать все модули, ставя перед всеми обращениями к указателю * не удобно. Может потом, когда структура программы устаканится, я уберу класс-обертку, но пока им удобно польльзоваться и он не влияет на производительность (в сравнении со ссылками). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 20:07 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
MasterZivЯ мало что понял из этого потока сознания. Это, наверное, от того, что что тратишь много энергии на критику. Ты же считаешь, что я даже класс от объекта отличить не могу... Ну и не трать свое время на общение с неучами, как нибудь сами разберемся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 20:12 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. А ну тут все правильно. Так как для операции d+d1 производится поиск возможных преобразований типа операндов к единому типу и для var такое преобразование есть: operator T, то все работает. А для += такого поиска преобразования не производится. Это связано с тем что операция + для встроенных типов определена как если бы она была свободной функцией, а операция += - как если бы она была методом (в этом случае потребовалось бы 2 последовательных неявных преобразования, а это запрещено правилами С++). Таким образом, вам действительно нужно в вашем шаблоне определить оператор += и прочие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:05 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyТаким образом, вам действительно нужно в вашем шаблоне определить оператор += и прочие. А не будет ошибок при использовании типов, где эта операция не определена, например, var<bool>? Я пока не проверял, просто заменил в одном месте программы x += y на x=x+y, чтобы убрать ошибку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:12 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Я то думал что вы определили оператор += в шаблоне и для инстанцирования bool это не работало (по вашим словам из-за отсутствия += у bool). Так вот, для bool должно работать (если конечно вы не вызываете += для var<bool>) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:14 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsА не будет ошибок при использовании типов, где эта операция не определена, например, var<bool>? Не будет ошибок, т.к. тела шаблонов проверяются только при их явном вызове. Это относится как телам функций в шаблонных классах(а так же и другим объявлениям внутри класса), так и телам функций-шаблонов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:18 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsMasterZivЯ мало что понял из этого потока сознания. Это, наверное, от того, что что тратишь много энергии на критику. Ты же считаешь, что я даже класс от объекта отличить не могу... Ну и не трать свое время на общение с неучами, как нибудь сами разберемся. Спасибо, что предупредил, не буду и тратить.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:18 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Кстати, а почему вы решили что += не определена для bool? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:23 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
inline T& operator=(T *src) { _ptr = src; return *_ptr; } template <typename TT> inline T& operator=(const TT &src) { assert(_ptr!=NULL); *_ptr = (T)src; return *_ptr; } — Плохой стиль. Ты одновременно позиционируешь ЭТО И как указатель, и как ссылку. Плохо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:24 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Вчера как раз на этом остановился, не успел проверить. Проверил сейчас, действительно работает - главное не вызывать операцию для тех типов, где она не определена. Тут вот еще вопрос вчера возник, с которым я пока не разобрался. Мне непонятно, почему одновременно приходится прописывать: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Если убрать Т(), то перестают работать выражения вида {double} += {var<double>}, а если убрать ТТ(), то перестают работать вызовы функций F(_variant_t arg), где в качестве arg подставляется var<double>. По идее ТТ() должен полностью перекрывать Т(), но на деле как будто ТТ() рассматривается для всех типов, кроме Т (т.е. double в var<double>). При этом в аналогичной ситуации оператор =(ТТ &src) перекрывает оператор =(Т &src). Собственно мой вопрос в в том, как устроен алгоритм выбора подходящего шаблона? В частности, для конструкции template <typename TT> inline operator TT() внутри класса template <typename T> class var для реализации шаблона var<double> тип ТТ может рассматриваться, как double или нет (т.е. ТТ - это любой тип, кроме Т=double)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:35 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
[quot andreybs]BagaBagaЕсть только одно неудобство. Например, для double есть операция +=, а для bool ее нет. Поэтому перегрузку оператора += не получается включить в состав класса var<T>. Если речь идёт о вашей обёртке, то я принципиально не вижу проблемы. Например, вот такой код Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. выводит Код: plaintext 1. 2. 3. Я намеренно не использовал шаблоны, чтобы за "деревьями" не "потерять лес". Переписать это на шаблоны нет проблем. Там, конечно, нужен будет не только оператор, принимающий double (в вашем случае - тип-параметр), но и оператор, принимающий в качестве входа "такую же обёртку" (а также аналогичный конструктор), но в данном случае это суть не изменит, а строк добавит. Для особых случаев (для тех типов, для которых операция *ptr +=d не определена) вы можете сделать специализацию шаблона и задать то поведение, которое нужно в соответствии с вашей задачей (если такая операция просто недопустима, то можно породить исключение, правда, мне это кажется нелогичным - хотеть оператор для "общего" случая и не иметь понятия о желаемом его поведении). Но я всё равно не понимаю вашей задачи (да она и не озвучена). Использование стандартного контейнера предполагает использование предоставливаемых им штатных средств. Знание того, что вектор хранит свои структуры в непрерывном "куске памяти" полезно при обеспечении совместимости с С-кодом, а вот в других случаях - это верный способ "выстрелить себе в ногу". В отличии от memset, контейнер при создании каждого элемента вызывает его конструктор, ну, и деструктор при выходе из области жизни. Простое же копирование допустимо только для "плоских" типов, что идёт в разрез со "сложными непонятно где определёнными типами". Приведу простой пример: создание простого массива (через new) и его последующая инициализация с memset по сравнению с vector<int>v(elem_number, 0) давало выигрыш менее 0.5%. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:40 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyandreybs, Кстати, а почему вы решили что += не определена для bool? :) У меня компилятор предупреждение выдает... warning C4804: +=: небезопасное использование типа "bool" в операции Полагаю, он bool в int конвертит и работает с true=(int)1, а false=(int)0... Кривотина какая то... :) Наверное, будет работать без варнинга только для BOOL, или что там у нас определено, как int... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:40 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaНо я всё равно не понимаю вашей задачи (да она и не озвучена). Все просто - создается массив структур: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Чтобы обнулить var_n для структур B, нужно в цикле их все перебрать и задать B.var_n=0. В то время для обнуления структур А достаточно с помощью memset обнулить массив, где хранятся значения. Если обнуление делается много миллионов раз, то второй способ быстрее. Аналогично, можно в любой момент сделать "снимок" системы, сохранив массив значений в отдельный буфер и восстановить систему, загрузив массив из буфера. Опять же это быстрее циклического перебора структур. BagaBagaсоздание простого массива (через new) и его последующая инициализация с memset по сравнению с vector<int>v(elem_number, 0) давало выигрыш менее 0.5%. А кто сказал, что внешним массивом не может быть вектор? Речь идет не об инициализации массива, а о массовых операциях изменения значений массива в сравнении с изменением значений каждой структуры в цикле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 21:59 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyandreybsИзвестно, что обращение к переменной по указателю type* осуществляется в два шага: считывание адреса из указателя, переход по адресу. В то же время ссылка type& содержит прямой адрес на значение переменной в памяти, поэтому обращение по ссылке занимает на один шаг меньше. При выполнении высокопроизводительных операций эта разница ощутима Это не так. На уровне машинного кода реализация указателя и ссылки одинаковая, поэтому никакой разницы в скорости у них нет. (Где вы вообще про такое прочли?) Соответственно, необходимость изменения ссылок надумана. Используйте указатели. Ссылка int & соответствует int *const __restrict - в этом случае они всегда соптимизируются одинаково. Если указатель без const или __restrict, то у него меньше возможностей к оптимизации, чем у ссылки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 22:53 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
int *const __restrict, А сможете привести пример, когда будет разный код сгенерирован? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 23:10 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
int *const __restrict, Если обычному указателю приписать __restrict, то у него будет больше возможностей к оптимизации? т.е. в моем случае вместо T* _ptr; использовать T* __restrict _ptr; Есть еще хинты в оптимизации работы указателей, на которые следует обратить внимание? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 23:19 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Вы не до конца поняли. Нужно и const и __restrict. То есть вы не сможете в указатель присваивать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 23:22 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Топикстартеру на заметку: Вообще, обнуление структур через memset - штука небезопасная, надо знать, какие структуры. POD структуры — все будет ок. Не POD — будет беда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 23:39 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, похоже, я не могу понять вас (используемую вами терминологию). Если у нас есть массив my_class arr[100] то у меня в каждом элементе массива хранится одна структура. Это значит, что я её могу обойти, например, так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Я это к тому, что в любом случае ваше var<double> var_n хранится в структуре. Это, конечно, может быть указатель (или ссылка) на что-то "снаружи". И вот тут я начинаю непонимать: речь идёт об "очистке" одной структуры? Тогда вы работаете с одной единицей и "валовые операции" вам не нужны. Вы меняете что-то для "кучи" структур? Но как тогда построить соответствие между местом в массиве (или векторе или что вы там используете) и местом в этом "снаружи"? То, что вы озвучиваете, мне напоминает ситуацию: у меня есть два поля, одно из которых меняется редко, а другое - часто. Заведу под них массивы: double rare[maxsize] double freq[maxsize] Но мне же почему-то неудобно показать, что это два массива. Поэтому я сделаю псевдообвязку, в которой одно поле будет указывать (а уж как - через указатели или ссылки - не важно) на rare[i], а во второй - на freq[i]. И заведу массив такого же размера для обвязок (не создавать же ручками кучу переменных). Вот только тогда и можно "показать фокус" и почистить скопом freq, не пробегаясь по массиву обвязок. Но это автоматически означает, что у вас в массиве freq могут храниться только "плоские" POD-типы. Про структуры и классы придётся забыть - по причине особенностей хранения данных (например, вследствие выравнивания структур) как минимум. А так, без примера очищения "скопом", я не могу понять, о чём вообще речь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2013, 23:59 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
MasterZivТопикстартеру на заметку: Вообще, обнуление структур через memset - штука небезопасная, надо знать, какие структуры. POD структуры — все будет ок. Не POD — будет беда. Обнуляются не структуры, а только некоторые их члены, значение которых вынесено в отдельный массив данных по указателю. В итоге обнуляется массив данных, а не массив структур. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 08:17 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaТо, что вы озвучиваете, мне напоминает ситуацию: у меня есть два поля, одно из которых меняется редко, а другое - часто. Заведу под них массивы: double rare[maxsize] double freq[maxsize] Но мне же почему-то неудобно показать, что это два массива. Поэтому я сделаю псевдообвязку, в которой одно поле будет указывать (а уж как - через указатели или ссылки - не важно) на rare[i], а во второй - на freq[i]. И заведу массив такого же размера для обвязок (не создавать же ручками кучу переменных). Вот только тогда и можно "показать фокус" и почистить скопом freq, не пробегаясь по массиву обвязок. Вы все верно поняли. Такой "изворот" нужен из-за того, что сами вычисления делаются поэлементо со структурами и их членами (от этого не уйти), а инициализация данных для вычислений осуществляется массово за один раз через внешние массивы с данными (для ускорения каждого цикла вычислений). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 08:26 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyandreybs, Вы не до конца поняли. Нужно и const и __restrict. То есть вы не сможете в указатель присваивать :) Если я правильно понял, что написано здесь и здесь , то __restrict имеет определенный смысл - мы как бы привязываем указатель к определенной области памяти и обещаем его не перезаписывать указателями из других областей. Как раз мой случай, а отсутствие const как раз разрешает менять указатель. Полагаю, нельзя будет ему присваивать NULL - не проблема, можно инициализировать статической переменной типа static T __restrict init_var; (если такая запись проканает). Вобщем, надо будет попробовать и посмотреть на изменение скорости работы... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 08:41 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, Да не будет никакого изменения в скорости. Вы не там оптимизируете. Оптимизировать надо алгоритм, а не машинный код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 14:38 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyint *const __restrict, А сможете привести пример, когда будет разный код сгенерирован? :) Сходу не приведу, но недавно встречался как раз такой случай, когда заданные в коде константы в compile-time проваливались глубоко внутрь кода через *const __restrict, и сильно оптимизировали код, в том время, как без этих квалификаторов такого не происходило. andreybs , Вообще это C-style подход. А в C++ нет ничего проще, чем использовать ссылку &, если мы конечно работаем не в google, где разрешены только константные ссылки в параметрах функций :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 15:22 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsОбнуляются не структуры, а только некоторые их члены, значение которых вынесено в отдельный массив данных по указателю. В итоге обнуляется массив данных, а не массив структур. Вот тут у меня с вами принципиальное расходение в терминологии: ничего в структурах не обнуляется. Там как хранились "редкие данные", так и хранятся. Как хранился адрес (в виде указателя или ссылки - не важно) на "частые" данные, так и хранится. А что происходит с тем куском памяти, ссылка на который хранится в структуре, структуре глубоко всё равно - хоть обнуляйте, хоть генератором случайных чисел заполняйте. И да, похоже, сначала нужно хорошо оптимизировать алгоритм, а уже потом пытаться выиграть на "массовом заполнении" вместо "индивидуального". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 19:12 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
*const __restrict andreybs , Вообще это C-style подход. А в C++ нет ничего проще, чем использовать ссылку &, если мы конечно работаем не в google, где разрешены только константные ссылки в параметрах функций :) Мне нужно инициализировать ссылку не в момент создания экземпляра содержащий ее структуры, а после создания всех экземпляров структур. Кстати, я стараюсь везде использовать константные ссылки в качестве параметров функций... :) Не знаю, как там оптимизатор решит, но так точно не будет создаваться копии параметра в области видимости функции... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 20:51 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaВот тут у меня с вами принципиальное расходение в терминологии: ничего в структурах не обнуляется. Там как хранились "редкие данные", так и хранятся. Как хранился адрес (в виде указателя или ссылки - не важно) на "частые" данные, так и хранится. А что происходит с тем куском памяти, ссылка на который хранится в структуре, структуре глубоко всё равно - хоть обнуляйте, хоть генератором случайных чисел заполняйте. Разумеется, в структурах физически ничего не обнуляется, ведь они содержат указатели. :) BagaBagaИ да, похоже, сначала нужно хорошо оптимизировать алгоритм, а уже потом пытаться выиграть на "массовом заполнении" вместо "индивидуального". Какая основная идея оптимизации многократно повторяющейся последовательности? - Упростить тело цикла. Вот как раз замена вложенных циклов на "массовые операции" и позволяют ускорить тело цикла, пусть даже в ущерб быстродействию подготовки данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2013, 21:01 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Если нельзя, но очень хочется, то ... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. andreybsКакая основная идея оптимизации многократно повторяющейся последовательности? - Упростить тело цикла. Вот как раз замена вложенных циклов на "массовые операции" и позволяют ускорить тело цикла, пусть даже в ущерб быстродействию подготовки данных. Очень просто - путём уменьшения количества операций. Т.е. выноса обнулений за циклы и т.п. Используемый вами механизм тоже не даётся даром. Вы используете по одной ссылке на каждый элемент массива (в своей структуре-обёртке). Она не даётся даром. На указатель нужна память, в размере (в большинстве реализаций) 32bit (64-разрядные системы для простоты не рассматриваю). Это значит, что для "частых" данных вы практически удваиваете необходимое количество памяти - на сами данные и на указатель на эти данные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 20:27 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaЕсли нельзя, но очень хочется, то ... Я думал об этом. Отказался от этого подхода из-за того, что в структурах есть еще и массивы указателей на другие связанные структуры. Частое копирование массивов - дело невыгодное для производительности, а передача ссылки на массив по цепочке выглядит не слишком красиво и не прозрачно. Непонятно, кто должен уничтожать массив при уничтожении структуры, значит потребуется добавить деструктор и т.д. структура плавно превращается в класс... BagaBagaИспользуемый вами механизм тоже не даётся даром. Вы используете по одной ссылке на каждый элемент массива (в своей структуре-обёртке). Она не даётся даром. На указатель нужна память, в размере (в большинстве реализаций) 32bit (64-разрядные системы для простоты не рассматриваю). Это значит, что для "частых" данных вы практически удваиваете необходимое количество памяти - на сами данные и на указатель на эти данные. Согласен, ничего не дается даром, я жертвую избыточным объемом данных. Но в моем случае это приемлемые потери, ибо одновременно удерживаемых в памяти структур с такими указателями не так много (не более 2-3 тыс), а вот обращение к ним весьма интенсивное. Да и "частых" данных всего 3 поля double, но они ооочень "частые"... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 21:28 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, А что за прикладная область? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 21:32 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, вообще-то этот код Код: plaintext 1. делает ровно то, что спрашивается в заголовке топика: он изменяет адрес ссылки (в данном случае две ссылки, хранящиеся внутри структуры). Или вам было нужно что-то другое? Но тогда что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 21:54 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Если нужно пересвязать с другими переменными, то можно и так (используя другой конструктор) Код: plaintext 1. в s3 будут храниться ссылки на v1 и v2, вне зависимости от того, но что они ссылались раньше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 22:00 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyandreybs, А что за прикладная область? Нейронные сети. Иду на рекорд... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 23:34 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
BagaBagaandreybs, вообще-то этот код Код: plaintext 1. делает ровно то, что спрашивается в заголовке топика: он изменяет адрес ссылки (в данном случае две ссылки, хранящиеся внутри структуры). Или вам было нужно что-то другое? Но тогда что? Вы все верно ответили по теме, спасибо за совет. Просто момент создания темы я ошибочно полагал, что ссылки по определению быстрее указателей... Спасибо форумчанам, помогли разобраться и это помогло мне найти неплохое решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2013, 23:37 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsAnatoly Moskovskyandreybs, А что за прикладная область? Нейронные сети. Иду на рекорд... :) А, тупиковая ветвь ИИ. Самое неблагодарное занятие - оптимизировать по крохам алгоритм, чью работоспособность еще предстоит доказать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 00:07 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyА, тупиковая ветвь ИИ. Самое неблагодарное занятие - оптимизировать по крохам алгоритм, чью работоспособность еще предстоит доказать :) Довольно субъективное и весьма спорное утверждение. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 08:40 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybs, у вас обнуление - это самая частая операция с данными, чтобы оптимизировать скорость ее выполнения за счет замедления других операций? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 09:39 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsВсе просто - создается массив структур: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Чтобы обнулить var_n для структур B, нужно в цикле их все перебрать и задать B.var_n=0. В то время для обнуления структур А достаточно с помощью memset обнулить массив, где хранятся значения. Если обнуление делается много миллионов раз, то второй способ быстрее.Да, но только любое обращение (и чтение и запись) к A.var_n медленнее, чем к B.var_n ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 09:51 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsAnatoly MoskovskyА, тупиковая ветвь ИИ. Довольно субъективное и весьма спорное утверждение. :) Что значит субъективное? НС придуманы уже полвека как. Может и ИИ существует уже? Вот то-то же ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 12:55 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
?andreybs, у вас обнуление - это самая частая операция с данными, чтобы оптимизировать скорость ее выполнения за счет замедления других операций? Да, одна из... ?Чтобы обнулить var_n для структур B, нужно в цикле их все перебрать и задать B.var_n=0. В то время для обнуления структур А достаточно с помощью memset обнулить массив, где хранятся значения. Если обнуление делается много миллионов раз, то второй способ быстрее.Да, но только любое обращение (и чтение и запись) к A.var_n медленнее, чем к B.var_n[/quot] Экспериментальным путем выявлено, что замена переменных на указатели замедляет работу в среднем на 300тиков на миллион итераций вычисления 3,5%. Переход на указатели дал не менее 17% прироста производительности при обучении сети. Поскольку обучение - самая тяжелая операция, то переход на указатели оправдан. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 22:41 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyandreybsпропущено... Довольно субъективное и весьма спорное утверждение. :) Что значит субъективное? НС придуманы уже полвека как. Может и ИИ существует уже? Вот то-то же Ну, генетику придумали тоже не вчера, но человека пока никто не клонировал. Тем не менее, это не мешает использовать генетику в промышленных отраслях. И кто вам сказал, что "ИИ" не существует? Приведите определение "ИИ"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.09.2013, 22:47 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsИ кто вам сказал, что "ИИ" не существует? Приведите определение "ИИ"? Давайте не будем :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 01:15 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyandreybsИ кто вам сказал, что "ИИ" не существует? Приведите определение "ИИ"? Давайте не будем :) Вот, народ насмотрится фильмы про всяких терминаторов, потом думает, что ИИ - это неубиваемый металлический чувак с пулеметом... :) На самом деле прототипы ИИ уже давно существуют: - Deep Blue -Системы распознавания речи , а так же системы распознавания образов, системы ведения цели (наведения на цель). - MYCIN - IBM Watson и т.д... Другое дело, что элементная база пока не доросла. Но пройдет несколько десятков лет и найдут новую базу (может смогут строить квантовые компьютеры ) и тогда вопрос с параллельными вычислениями будет решен кардинально, а построение сложного ИИ станет вполне реальным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 09:12 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Кстати, оказывается Google уже анонсировал в этом году проект, о котором я написал выше . Не исключаю, что 90% (или больше) сочтут это полным бредом и будут тихо посмеиваться в стороне. Но лично я считаю это вполне реальным проектом, который может дать серьезный толчок в сфере разработки суперкомпьютеров и ИИ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 09:20 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsНо пройдет несколько десятков лет Что и требовалось доказать. ИИ на НС - тупиковая ветвь. Как и летательные аппараты с машущими крыльями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 12:38 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Вы знаете более перспективные направления ИИ, раз нейросети считаете тупиковыми? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 13:13 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Лучшие ИИ строятся на ГСЧ. Стохастические алгоритмы рулят. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 13:17 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
andreybsВы знаете более перспективные направления ИИ, раз нейросети считаете тупиковыми? :) На данный момент перспективных нет. И это не смешно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 16:01 |
|
||
|
изменить адрес ссылки
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Полагаю, это вопрос терминологии - что называть "настоящим ИИ" и какие направления считать "перспективными". Вот, товарисч с постом выше про стохастические методы (немного не в тему) напомнил про стохастические модели, которые позволяют реализовать логику квантового процессора, на базе которого за счет высокой степени параллелилизма вычислений можно реализовывать самые сложные нейросети, а следовательно и ИИ. Куда уж еще перспективнее? На тех же принципах строится обработка информации в мозгу человека. Хочется верить, что у нас в голове реализованы самые перспективные технологии из известных в наше время... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 17:45 |
|
||
|
|

start [/forum/topic.php?all=1&fid=57&tid=2019985]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
49ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
79ms |
get tp. blocked users: |
1ms |
| others: | 296ms |
| total: | 466ms |

| 0 / 0 |
