2013-07-30 1 views
1

Итак, мне нужно обработать некоторые данные структуры, которые мне пришлось сжимать странным способом для MPI_Send/Recv.Арифметика указателя на необработанные данные

Невозможно удобно применить его к указателю на известный тип, на котором я хочу работать, а затем проиндексировать (поскольку я сжал структуру в смежные данные, не могу предположить ничего о выравнивании), поэтому Я должен пройти через это с помощью арифметики указателя. Проблема в том, чтобы поддерживать совместимость с MPI, эти данные даются как void *, а арифметика указателя на void * является незаконной.

Мой вопрос в основном стилистичен: есть ли лучший способ сделать это, чем бросать в char *, а затем делать свою арифметику указателя? Каковы были бы соображения эффективности при принятии пустоты *, кастинг на char *, выполнение моих вещей, а затем возврат к void *? Я не могу представить, чтобы стрелки указателей были ужасно дорогими.

G'day и спасибо большое.

ответ

3

Приводы указателей полностью бесплатны. Сделай это.

Указатель, имеющий тип, является понятным языком. Когда вы переходите на аппаратный уровень, указатель представляет собой целое число, которое используется как адрес памяти.

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

[Хорошо, на некоторых архитектурах есть некоторые случаи, когда указатели имеют специальную обработку за пределами «просто целые числа», но вы, вероятно, можете их игнорировать. Существуют также некоторые ABI, в которых разные типы указателей являются различными (например, FDPIC), но опять-таки, чья-то проблема.]

+0

А, это было легко. Благодарю вас. –

0

Ваше решение является звуковым. Много раз я сделал что-то вроде этого:

void handle_raw(void* data) { 
    // Use a uint8_t so pointer arithmetic is at a byte-level. 
    uint8_t* p = data;  
    uint16_t value; 

    // Read a 2-byte value at an arbitrary offset. 
    value = *(uint16_t*)(p + 0x42); 

    // Write a 2-byte value at an arbitrary offset. 
    *(uint32_t*)(p + 0x12) = 0xDEADBEEF; 
} 

Конечно, вы должны использовать константы для смещений, а также выполнять соответствующие проверки границ.

+0

То есть ** нет ** безопасно в этом случае. На многих архитектурах ваш код не будет работать, если указатель не выровнен по 2 байтам. Кроме того, тип-punning имеет проблемы с псевдонимом: используйте союз. – ams

0

Есть ли какая-то особая причина, по которой вам нужно самому упаковать буферы? Действительно ли вы фактически сжимаете данные в смежном буфере до операции MPI? Если это так, ваше сжатие плюс время передачи должно быть ниже, чем просто передача. Если это так, то я вижу это как хорошее оправдание.

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

Вы можете сделать поиск в Интернете с помощью чего-то типа «Пример данных типов данных MPI» и получить гораздо лучшие объяснения, чем то, что я могу вкратце написать здесь.

+0

Проблема заключается в том, что структуры содержат вещи, которые не являются данными, а индексы в стек значений, которые я хочу отправить. Так любопытно, как указатели. Отправка этих вещей будет бессмысленной, как отправка указателей, поэтому мне нужно «разыгрывать» их как-то.Использование только производного механизма типа данных для достижения этого находится где-то между сложным и невозможным, поскольку смещение каждого значения в этом стеке не является постоянным относительно начала структуры, содержащей его индекс. –

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

  • Нет связанных вопросов^_^