少なくとも ARMv5 までの ARM CPU では、ワード アラインされていないメモリ アドレスへのランダム アクセスは許可されていません。この問題について詳しくは、http: //lecs.cs.ucla.edu/wiki/index.php/XScale_alignmentを参照してください。解決策の 1 つは、コードを書き直すか、最初からこの配置を検討することです。ただし、その方法は述べられていません。ストリーム内でワード整列されていない 2 バイトまたは 4 バイトの整数があるバイト ストリームを考えます。パフォーマンスを大幅に低下させることなく、スマートな方法でこのデータにアクセスするにはどうすればよいでしょうか?
問題を説明するコード スニペットがあります。
#include <stdio.h>
#include <stdlib.h>
#define BUF_LEN 17
int main( int argc, char *argv[] ) {
unsigned char buf[BUF_LEN];
int i;
unsigned short *p_short;
unsigned long *p_long;
/* fill array */
(void) printf( "filling buffer:" );
for ( i = 0; i < BUF_LEN; i++ ) {
/* buf[i] = 1 << ( i % 8 ); */
buf[i] = i;
(void) printf( " %02hhX", buf[i] );
}
(void) printf( "\n" );
/* testing with short */
(void) printf( "accessing with short:" );
for ( i = 0; i < BUF_LEN - sizeof(unsigned short); i++ ) {
p_short = (unsigned short *) &buf[i];
(void) printf( " %04hX", *p_short );
}
(void) printf( "\n" );
/* testing with long */
(void) printf( "accessing with long:" );
for ( i = 0; i < BUF_LEN - sizeof(unsigned long); i++ ) {
p_long = (unsigned long *) &buf[i];
(void) printf( " %08lX", *p_long );
}
(void) printf( "\n" );
return EXIT_SUCCESS;
}
x86 CPU での出力は次のとおりです。
filling buffer: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
accessing with short: 0100 0201 0302 0403 0504 0605 0706 0807 0908 0A09 0B0A 0C0B 0D0C 0E0D 0F0E
accessing with long: 03020100 04030201 05040302 06050403 07060504 08070605 09080706 0A090807 0B0A0908 0C0B0A09 0D0C0B0A 0E0D0C0B 0F0E0D0C
ATMEL AT91SAM9G20 ARMv5 コアでは、次のようになります (注: これは、この CPU の予想される動作です!):
filling buffer: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
accessing with short: 0100 0100 0302 0302 0504 0504 0706 0706 0908 0908 0B0A 0B0A 0D0C 0D0C 0F0E
accessing with long: 03020100 00030201 01000302 02010003 07060504 04070605 05040706 06050407 0B0A0908 080B0A09 09080B0A 0A09080B 0F0E0D0C
したがって、アライメントされていないアドレスでバイトストリームにアクセスしたい、またはアクセスする必要がある場合:ARMで効率的に行うにはどうすればよいですか?