2012-04-27 7 views
0

私は非常に少ないリソースを使用し、非常に高速でなければならないアプリケーションを開発しています。私のアプリでは、画像から得たバイトを含むunsigned char* rawDataを使用しています。したがって、このrawData配列では、いくつかのバイトを保持しなければならず、他はゼロに設定しなければなりません。しかし、私はループを使用することはできません(そうでなければ、各バイトを実行してゼロに設定することができます)。unsigned charの使用。どのようにループを使用せずに要素を置き換えるには?

ここに質問があります。

Q1)C

Q2)にZeroMemoryなどObjective Cの内の任意の方法は、任意のループを使用することなく、ゼロにnessecaryバイトを設定する他の方法が存在しています。

ありがとうございました...

P.S.もし何かのコードを提供することができます...

+2

'memset'はあなたが望むことをしますか? –

+0

お返事ありがとうございました。しかし、私は 'memset'の使い方を理解できませんでした。そして私はそれが私が望むことをしないと思う。 'setZero:rawData FromByte:0 ToByte:someByte' – Garnik

+0

' memset'が助けになると思う...これは唯一の方法です... – Garnik

答えて

2

バッファのサイズがわからない場合は、ループなしで行うことはできません。あなた自身でループを記述しなくても、strlenのようなものを呼び出すとループが発生します。ここでもループとして再帰をカウントしています。

保持するバイトとゼロに設定するバイトをどのように知っていますか?これらのバイトが既知の位置にある場合、ベクトル演算を使用してバイトの一部をゼロにし、他のバイトをゼロにすることができます。以下の例は、rawDataの最初の64バイトを超えるだけでもバイトをゼロに:

__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の各バイトの上位ビットがzerosに対応する値をrawDataにコピーされ、1の場合。これらのマスクされたコピーのシーケンスを使用して、いくつかのバイトを素早く置き換えることができます。結果のマシンコードはSSE操作を使用するため、実際は非常に高速です。これは必須ではありませんが、rawDataが16バイト境界である場合、SSE操作は非常に高速に実行されます。

ARMをターゲットにしている場合は申し訳ありません。 NEONの組み込み関数は似ていますが、同一ではないと思います。

+0

うーん...最初のことは分かりません。私の 'rawData'のサイズ(この' unsigned char * rawData =(unsigned char *)calloc(gridSize * gridSize、sizeof(unsigned char)); ')のサイズは常に4です。それが4byteを返すと思います。 2番目の事は、私は私のバッファ(rawData)のサイズをstrlenなしで持つことができます。そして3番目の問題、申し訳ありませんが、私はあなたのコードを理解していませんでした。 :( – Garnik

関連する問題