Вопрос

Я экспериментирую с OpenCL для увеличения скорости нашего программного обеспечения.Мы много работаем с картами и для упрощения представляем карту в виде std::vector< std::vector >.API OpenCL принимает в качестве аргументов необработанные указатели в стиле c, например int* в приведенном выше случае.

Мои вопросы:

  • Есть ли в stl гарантии реализации того, что вектор внутренне последователен в памяти?
  • Могу ли я безопасно привести std::vector к int* и ожидать, что это сработает?
  • Могу ли я предположить, что это верно и в случае вектора векторов?Я ожидаю, что вектор будет содержать другие данные о состоянии, или проблемы с выравниванием, или, может быть, что-то еще...
  • Как лучше всего подойти к этому?Написать собственную 2D-структуру данных, которая содержит внутренний непрерывный буфер в памяти, и работать с ней?Мне пришлось бы много копировать в/из векторов...

Спасибо.

Это было полезно?

Решение

Есть ли в stl гарантии реализации того, что вектор внутренне последователен в памяти?

Начиная с C++03, да, вектор гарантированно использует непрерывную память.(В C++98 была случайная лазейка, из-за которой реализация могла гипотетически использовать несмежное хранилище, но она была исправлена ​​в версии стандарта 2003 года - и на самом деле реализации не было. использовал несмежное хранилище, потому что это была бы ужасная идея)

Могу ли я безопасно привести std::vector к int* и ожидать, что это сработает?

Обычный способ &v[0]. (&*v.begin() вероятно, тоже сработает, но я, кажется, припоминаю, что в стандарте есть какая-то расплывчатая формулировка, которая делает это не на 100% надежным)

Нет.Почему вы ожидаете, что это сработает?Вектор — это класс.Это не указатель.Это просто содержит указатель.

Могу ли я предположить, что это верно и в случае вектора векторов?Я ожидаю, что вектор будет содержать другие данные о состоянии, или проблемы с выравниванием, или, может быть, что-то еще...

Вектор ведет себя одинаково, что бы вы в нем ни хранили.Если вы создадите вектор из векторов, вы получите объект, который содержит указатель на массив, выделенный в куче, где каждый элемент является объектом, содержащим указатель на массив, выделенный в куче.

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

Другие советы

  • Есть ли в stl гарантии реализации этого вектора,
    внутри, последовательно в памяти

Да, это динамический массив.Стандарт гарантирует, что объекты внутри вектора сохраняются последовательно.

  • Могу ли я безопасно привести std::vector к int* и ожидать, что это сработает?

Нет, но вы можете использовать метод Begin() и использовать его в качестве указателя.

  • Есть ли в stl гарантии реализации этого вектора,
    внутри, последовательно в памяти

Нет, поскольку вектор может содержать некоторые внутренние переменные-члены, весь двумерный массив не будет непрерывной ячейкой памяти.

Есть ли в stl гарантии реализации того, что вектор внутренне последователен в памяти?

Хотя я не могу здесь цитировать стандарты, я видел код в высококачественных библиотеках, допускающий такую ​​компоновку (а именно: ПОКО).

Могу ли я безопасно привести std::vector к int* и ожидать, что это сработает?

В частности, вы не можете переделать сам вектор.Но я видел следующий код:

std::vector<int> vec;
int* ptr = &vec[0];

Могу ли я предположить, что это верно и в случае вектора векторов?Я ожидаю, что вектор будет содержать другие данные о состоянии, или проблемы с выравниванием, или, может быть, что-то еще...

Вероятно, вы не можете преобразовать вектор векторов в линейный массив.Каждый вектор зарезервирует свой собственный диапазон памяти, и нельзя ожидать, что все эти диапазоны будут последовательными.

В комментарии вы упомянули, что работаете с данными размером до 2500x2500xsizeof(double).В этом случае я бы предложил использовать один вектор вместо вектора векторов.Выделите элементы NxM в векторе и оберните его в класс, предоставляющий двумерную индексацию, если хотите.Вы получаете все преимущества векторной обработки с минимальными издержками, и все ваши данные по-прежнему находятся в непрерывной памяти для быстрой обработки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top