2012-04-27 5 views
0

Я разрабатываю приложение, которое должно использовать очень мало ресурсов и быть очень быстрым. И в моем приложении я использую unsigned char* rawData, который содержит байты, полученные из изображения. Поэтому в этом массиве rawData я должен оставить несколько байтов, а другие - равными нулю. Но мне не разрешено использовать какой-либо цикл (в противном случае я могу просто пропустить каждый байт и установить нулевое значение).Работа с unsigned char. Как заменить элементы без использования цикла?

Итак, вот вопросы.

Q1) Есть ли способ, в Objective C, как в ZeroMemory C

Q2) Есть ли какие-либо другие способы, чтобы установить nessecary байт в ноль без использования какого-либо цикла.

Thanks In Advance ...

P.S. Может предоставить некоторый код, если nessecary ...

+2

Будет ли 'memset' делать то, что вы хотите? –

+0

Спасибо Оли за ваш ответ. Но я не мог понять, как использовать 'memset'. И я думаю, что это не сделало бы того, что я хочу. Мне нужно что-то вроде этого: 'setZero: rawData FromByte: 0 ToByte: someByte' – Garnik

+0

Хммм думаю, что' memset' поможет ... Это только путь ... – Garnik

ответ

2

Если вы не знаете размер буфера, вы не можете сделать это без цикла. Даже если вы не пишете цикл самостоятельно, вызов чего-то типа strlen приведет к циклу. Я тоже рассчитываю рекурсию как петлю.

Как узнать, какие байты хранить и какие значения равны нулю? Если эти байты находятся в известных позициях, вы можете использовать векторные операции для обнуления некоторых из байтов, а не других. Следующий пример обнуляет только четные байты в течение первых 64 байт rawData:

__m128i zeros = _mm_setzero_si128(); 
uint8_t mask[] = {8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0}; 
__m128i sse_mask = _mm_load_si128(mask); 
_mm_maskmoveu_si128(zeros, sse_mask, &rawData[0]); 
_mm_maskmoveu_si128(zeros, sse_mask, &rawData[16]); 
_mm_maskmoveu_si128(zeros, sse_mask, &rawData[32]); 
_mm_maskmoveu_si128(zeros, sse_mask, &rawData[48]); 

Если старший бит каждого байта в mask равен 1, то соответствующее значение в zeros будет скопировано в rawData. Вы можете использовать последовательность этих замаскированных копий, чтобы быстро заменить некоторые байты, а не другие. В результате машинный код использует операции SSE, поэтому это происходит довольно быстро. Это не требуется, но операции SSE будут выполняться намного быстрее, если rawData будет выровнен на 16 байт.

Извините, если вы настроите ARM. Я считаю, что NEON intrinsics похожи, но не идентичны.

+0

Хммм ... Первое, что я не знаю, почему, может быть, это должно быть так, но размер моего 'rawData' (я инициализирую его так: unsigned char * rawData = (unsigned char *) calloc (gridSize * gridSize, sizeof (unsigned char));') всегда 4, I думаю, что он возвращает 4 байт. Во-вторых, я могу иметь размер моего буфера (rawData) без каких-либо strlen. И третья проблема, извините, но я не понял ваш код. :( – Garnik

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