|
Регистрация | Файлы | Правила | Альбомы | Дневники | Справка | Пользователи | Календарь | Поиск | Сообщения за день | Все разделы прочитаны |
Отвергнутые патчи Патчи, отвергнутые от приёма в GIT |
|
Опции темы | Поиск в этой теме | Опции просмотра |
26.03.2011, 05:45 | #1 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Overhead в базовой функции SendPacket()
Отправка клиенту больше данных чем нужно.
Отправляем - сколько выделили памяти для буфера, а не сколько туда положили. Баг, как вижу старый, на трине присутствует тоже ... У меня трафик снизился после исправления. Собственно код для чистого ядра: PHP код:
PHP код:
Последний раз редактировалось xex; 26.03.2011 в 05:52. |
2 пользователя(ей) сказали cпасибо: | rsa (26.03.2011) |
26.03.2011, 09:00 | #2 |
MaNGOS Dev
Регистрация: 07.03.2010
Сообщений: 314
Сказал(а) спасибо: 30
Поблагодарили 153 раз(а) в 83 сообщениях
|
Не путайте capacity() и size(). Первая возвращает число выделенных блоков под элементы вектора, вторая - число элементов.
Следовательно ваш патч ничего не исправляет. |
26.03.2011, 09:07 | #3 | |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Цитата:
Посмотри внимательно код ByteBuffer.h, там переопределено. Последний раз редактировалось xex; 26.03.2011 в 09:18. |
|
26.03.2011, 09:31 | #4 |
Пользователь
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
|
size_t size() const { return _storage.size(); }
и там же const static size_t DEFAULT_SIZE = 0x1000; _storage.reserve(DEFAULT_SIZE); Если не указан размер.. |
26.03.2011, 09:32 | #5 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
Я, если честно, не вижу в каких случаях мы можем так жестоко прокалываться... У нас _storage.size() обязан быть равен _wpos. Вы пробовали ставить ассерты дабы проверить ваши догадки?
|
26.03.2011, 09:33 | #6 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
zhenya, _storage.reserve() != _storage.resize(). первое изменяет значение, возвращаемое функцией capacity(), а второе еще и size().
P.S. xex, поставьте такой ассерт MANGOS_ASSERT(pct.size() == pct.wpos()); в функции WorldSocket::SendPacket() и отпишитесь, если он сработает. Надо быть уверенными в том, что трабла действительно имеет место т.к. по коду на первый взгляд проблем не видно Последний раз редактировалось Ambal; 26.03.2011 в 09:42. |
26.03.2011, 10:07 | #7 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Да вы чего? внимательно в код посмотрите-то.
size_t size() const { return _storage.size(); } размер ХРАНИЛИЩА (сколько мозгов выделили) size_t wpos() const { return _wpos; } размер сколько данных влили. Вообще неправильно класс в этом отношении написан. Ядерщики - исправляйте |
26.03.2011, 10:16 | #8 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
Не морочьте голову, поставьте ассерт как я сказал в предыдущем посте и если он сработает, отпишитесь каким образом у вас это вышло: номер пакета, настройки компрессии трафика и т.д.
|
26.03.2011, 10:17 | #9 |
MaNGOS Dev
Регистрация: 07.03.2010
Сообщений: 314
Сказал(а) спасибо: 30
Поблагодарили 153 раз(а) в 83 сообщениях
|
wpos() - позиция записи в буфер, ее можно передвинуть чтобы перезаписать какие-то данные. Если использовать ее для определения размера пакета можно напороться на неприятные баги.
_storage.size() - возвращает число байт, которые положили в буффер. Т.е. то что нужно, бага нет. |
26.03.2011, 10:21 | #10 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
|
26.03.2011, 10:44 | #11 | |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Цитата:
WorldPacket data(опкод, 1киллобайт). data << гайд; data << uint8(0); Киллобайт и передаётся, хотя там например гайд и 0ль - итого максимум 9 байт, ну плюс опкод 2 байта . Сам класс немного криво сделан... Последний раз редактировалось xex; 26.03.2011 в 10:57. |
|
26.03.2011, 10:53 | #12 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
Давайте вы не будете зря сотрясать воздух, а поставите ассерты и посмотрите, возможна ли в принципе та ситуация, о которой вы говорите. А она может быть возможна только в случае если неправильно используются функции size_t wpos(size_t wpos_) и void resize(size_t newsize)
|
26.03.2011, 11:01 | #13 |
MaNGOS Dev
Регистрация: 07.03.2010
Сообщений: 314
Сказал(а) спасибо: 30
Поблагодарили 153 раз(а) в 83 сообщениях
|
xex, изучайте std::vector...
|
26.03.2011, 11:53 | #14 | |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Цитата:
Это сюда никак... У меня всё работает больше недели. трафик снизился на серверах... Не хотите в ядро внедрить, ну ладно Я например и такие вещи использую в буффере, перенёс с Delphi: Код:
// boxa inline uint32 AlignMemW(uint32 size) { if (size & 1) return (size | 1) + 1; else return size; } inline uint32 AlignMemD(uint32 size) { if (size & 3) return (size | 3) + 1; else return size; } inline uint32 AlignMemQ(uint32 size) { if (size & 7) return (size | 7) + 1; else return size; } // boxa |
|
26.03.2011, 11:54 | #15 |
Новичок
Регистрация: 21.10.2010
Сообщений: 12
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
эм, кагбэ http://www.devx.com/tips/Tip/5328
Особенно замечаем " In addition, reserve() does not change the size of a vector; it only changes the vector's capacity." ВЫВОД: size() вернет столько, сколько туда записали... (либо ресайзнули вручную через resize(), но этот факт ничего не меняет) |
26.03.2011, 11:54 | #16 |
Пользователь
Регистрация: 08.03.2010
Сообщений: 47
Сказал(а) спасибо: 45
Поблагодарили 29 раз(а) в 13 сообщениях
|
Ещё добавлю для ядерщиков:
int WorldSocket::SendPacket (const WorldPacket& pct) пакет готов для отправки клиенту? - да. мы здесь меняем данные? - нет. pct.size() - размер выделенной памяти. pct.wpos() - сколько записали И НУЖНО ПЕРЕДАТЬ. Последний раз редактировалось xex; 26.03.2011 в 11:57. |
26.03.2011, 12:04 | #17 |
Новичок
Регистрация: 21.10.2010
Сообщений: 12
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
if (pct.size() != pct.wpos()) throw "FAIL!";
может на плюсах понятнее. |
26.03.2011, 12:20 | #18 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
|
26.03.2011, 12:37 | #19 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
|
26.03.2011, 12:47 | #20 |
MaNGOS Dev
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
|
Закрою я эту тему от греха подальше. Пусть наш Delphi-программист почитает про разницу между зарезервированной и использованной памятью в STL-контейнерах. А также поймет, что существование багов надо доказывать, а не тыкать пальцем в небо и кричать "там где-то есть бага, я знаю!".
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|
|