Использование памяти для массивов и векторов (64 бит)? - PullRequest
0 голосов
/ 24 марта 2020

Я храню большие данные и хочу оптимизировать память. Что меня смущает, так это следующее (компиляция 64 бит):

char a[10] = {1,2,3,4,5,6,7,8,9,10};
long long int b[10] = {1,2,3,4,5,6,7,8,9,10};
vector<char> x = vector<char>(10,0);
vector<long long int> y = vector<long long int>(10,0);
cout << sizeof(a) <<" "<< sizeof(b)<< " " <<sizeof(x) <<" "<< sizeof(y)<< endl;

печатает значения 10 80 24 24.

1) Использует ли char [10] только 10 байтов? Разве он не должен использовать 80 байтов, поскольку при 64-битной компиляции память может быть адресована только для 64-битных блоков?

2) Последние две строки: почему 24 (3 байта?) Это просто так структура вектора включает 24 байта данных?

3) Использует ли вектор символов с 1000 элементами тот же объем памяти, что и у вектора long long int с 1000 элементами?

Ответы [ 2 ]

2 голосов
/ 24 марта 2020

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

2) sizeof возвращает размер в байтах , а не в битах . std :: vector обычно реализуется как структура из 3 указателей, один для начала, конца и емкости:

struct vector
{
  int* begin;
  int* end;
  int* capacity;
};

Поскольку это 64-битная система, значения вашего указателя (адреса) будет 8 байтов (== 64 бита) . В результате значения size 3xpointer будут 24 (3 * sizeof (void *)) .

Какой бы тип данных вы ни сохранили в векторе, sizeof всегда будет возвращать 24 (на типичной 64-битной архитектуре)

3) sizeof рассчитывает только необработанный размер данных структура. Он не учитывает тот факт, что значение указателя внутри этой структуры имеет некоторую дополнительную динамически распределенную память. Чтобы получить полный размер, понадобится что-то вроде этого:

template<typename T>
size_t getUsedMemUsage(const std::vector<T>& vec)
{
  size_t size_of_vector_struct = sizeof(std::vector<T>);
  size_t size_of_single_element = sizeof(T);
  return size_of_vector_struct + size_of_single_element * vec.size();
}
template<typename T>
size_t getFullMemUsage(const std::vector<T>& vec)
{
  size_t size_of_vector_struct = sizeof(std::vector<T>);
  size_t size_of_single_element = sizeof(T);
  return size_of_vector_struct + size_of_single_element * vec.capacity();
}

Хотя это не совсем верно (например, ОС может использовать несколько дополнительных байтов для выравнивания распределения памяти и, вероятно, использует ~ 16 байт для отслеживания выделений) .

Так что нет, вектор длиной в 1000 длинных целых будет использовать меньше памяти, чем вектор из 1000 символов (примерно sizeof(long long int) / sizeof(char))

1 голос
/ 24 марта 2020

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

  1. Данные массива занимают непрерывную область памяти При этом выравнивания как такового не происходит, поскольку все элементы имеют одинаковый тип. Поэтому char[10] будет иметь размер 10 * 1 = 10 байт.
  2. std::vector выделяет память в куче, то есть хранит только указатель на выделенную память, но не сами элементы. std::vector сам хранит только указатель на выделенную память, размер выделенной памяти и количество элементов. Размер указателя составляет 8 байт, размер других элементов обычно также составляет 8 байт, поэтому sizeof(std::vector<...>) независимо от типа данных будет 8 + 8 + 8 = 24 байт.
  3. Я действительно ответил на этот вопрос выше. sizeof(std::vector<...>) практически не зависит от типа данных. Размер выделенной памяти в куче, напротив, зависит от типа данных. std::vector<long long>(1000) потребляет больше памяти, чем std::vector<char>(1000).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...