2010-02-15 4 views
1

Возможно, у меня есть глупый вопрос, как всегда, но почему-то я не могу понять, как хранить переменные, чтобы он был эффективным. Наш учитель на C++ просто бросил что-то о том, как размер хранимого типа данных влияет на скорость его хранения (например, поиск ближайшего достаточного непрерывного блока памяти), и я хотел бы узнать об этом больше. Не могли бы вы дать мне несколько указаний?Хранение данных эффективно

+0

Это домашнее задание? Если так, тег как таковой. –

+0

Tagged, No Refunds No Returns. –

+0

Это неясно. Совершенно очевидно, что вы говорите о динамическом распределении памяти или типах переменных или о том, что означает «эффективный» в этом контексте. –

ответ

2

В общем случае для числовых переменных (таких как счетчики циклов) вы должны использовать «int», и пусть компилятор выбирает наиболее эффективный размер для задачи. Если у вас есть определенная потребность в определенном размере (например, uint16 для 16-разрядной части заголовка пакета, получаемой из сети или аналогичной), используйте typedef, который дает этот конкретный размер на вашей конкретной платформе; в противном случае просто используйте int.

Это говорит о том, что ваш учитель, возможно, говорил о динамических распределителях памяти (т. Е. Код за «malloc» и «free»). Если вы запросите выделить 64 байта, скажем, распределитель отвечает за предоставление вам блока по крайней мере этого размера и отслеживания его, чтобы он мог быть возвращен в доступное хранилище при его освобождении. Об этом много информации, например, в Википедии: http://en.wikipedia.org/wiki/Dynamic_memory_allocation

+0

да, это, наверное, о чем он говорил .. многое, я проверю это – Pyjong

+0

Для счетчика циклов я хотел бы сказать, что это раздражает меня до конца, когда я вижу 'for (int i = 0 ; ...; ++ i) '> если он должен быть положительным, я бы предпочел увидеть его в типе, так что это ясно для всех. и, таким образом, я обычно заканчиваю «size_t» ... Кроме того, если функция, которую он использует в ожидании определенного типа, я бы предпочел применить ее с самого начала, зачем платить стоимость конверсии, когда это так просто? –

0

Вы имеете в виду постоянное хранение или выделение в памяти?

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

Постоянное хранение - совсем другая история.

+0

Я не знаю, о каком из этих двух терминов говорил мой учитель. он сказал что-то вроде этого, чтобы избежать утечек в памяти, вы должны как-то сначала выделить какое-то пространство, а затем сохранить переменные одного и того же типа рядом друг с другом, потому что если иногда не может случиться так, что ваша операционная система должна будет каким-то образом разбить данные или не будет, t использовать некоторое пространство вообще, потому что это было бы слишком неэффективно, чтобы разделить его. – Pyjong

0

Как хранить переменные редко вам. Но тип и, следовательно, размер переменной часто зависит от вас.

Возможно, он имел в виду такие вещи, как «если вам нужно хранить небольшое целое число, например, адрес улицы, вы, вероятно, не должны использовать long, а скорее short». Эти вещи, как правило, требуют довольно много знаний о доменах, легко оптимизировать себя в угол (например, о проблеме Y2K).

0

Один из способов - использовать переменные типы. Нет необходимости хранить значение от 1 до 10 в int64. Идея состоит в том, чтобы сопоставить возможные значения переменной с типом переменной, которая лучше всего соответствует ее возможным значениям. Это сократит используемую память, а в более сложных структурах данных сократит скорость обработки.

0

Скорость записи и получения данных зависит от производительности вашего локального механизма хранения. На современных процессорах есть регистры, 2 уровня кеша (L1 & L2), DRAM и иногда диск (через swap). Если шаблоны доступа и размер эффективно используют кеш L1 (т. Е. Малый и локально когерентный), то, как только данные находятся в L1, его нужно только загружать в регистры, к которым должен обращаться ЦП. Если требуемые данные находятся в кэше L2, сначала необходимо загрузить его в L1 перед загрузкой в ​​регистр для обработки. То же самое относится к DRAM для L2-L1 для регистров. Регистры быстрее, чем L1, L1 быстрее, чем L2, а DRAM просто медленно.

Herb Sutter сделал доклад, который решает эти вопросы несколько лет назад в NWCPP:

http://video.google.com/videoplay?docid=-4714369049736584770#

С точки зрения программирования, если ваши данные могут поместиться внутри строки кэша и должен быть повторно обращались или письменной to, у вас будет более высокая производительность из-за меньшего количества промахов кэш-памяти (в результате чего потребуется извлечь из более высокого уровня кеша).Это верно для всех уровней «кеша», если они регистрируются, L1, L2, DRAM, диск или отдаленный сервер.

0

Возможно, ваш учитель предположил, что при размещении объекта в куче (с new) весь процесс имеет тенденцию быть медленнее, чем больше объект. Я написал a little program для измерения этого эффекта.

Вот результаты я получаю (скомпилированные в режиме выпуска с VS2008 и оптимизации выключен):

Cost of allocating 1 chars: 0.104 microseconds 
Cost of allocating 4 chars: 0.1 microseconds 
Cost of allocating 16 chars: 0.104 microseconds 
Cost of allocating 64 chars: 0.128 microseconds 
Cost of allocating 256 chars: 0.192 microseconds 
Cost of allocating 1024 chars: 0.416 microseconds 
Cost of allocating 4096 chars: 1.28 microseconds 
Cost of allocating 16384 chars: 2.56016 microseconds 
Cost of allocating 65536 chars: 3.0722 microseconds 
Cost of allocating 262144 chars: 3.58423 microseconds 

Так что учитель был прав, выделяя огромные объекты могут быть значительно медленнее, чем выделение объектов нормального размера (но очень быстро, тем не менее, мы говорим о нескольких микросекундах в худшем случае).

Смежные вопросы