とりあえず、第2章 SIMDプログラミングの基礎を見ながらちょっと触ってみる。
2.3.2の例題プログラムをコンパイルしようとすると、
ソースを読んで、文脈的にvcの型が合わないんだろうと思って*をつけたらうまく動いた。
演習問題 (2-1)
1024の総和だと、SIMDを使わない場合と差が出なかったので、102400で試してみたところ、SIMDを使った方が遅かった(笑)。まあ、これは使い方を覚えるためのサンプルなので、そんなものだろう。
不思議なことに、SIMDを使ったほうはほぼuser time だけを消費し、SIMDを使わない方はほぼ sys time だけを消費した。
演習問題 (2-2)
後は、vector short と vector int の関係、メモリイメージ、vec_permの使い方が頭の中でリンクしなくて、結構はまってしまった。
長くなるので続きは次のエントリで。
2.3.2の例題プログラムをコンパイルしようとすると、
$ gcc -maltivec -mabi=altivec ex2-1.c -o ex2-1.elf ex2-1.c: In function main: ex2-1.c:14: error: incompatible types in assignmentなんて怒られる。(あ、ソースファイル名は変えてあります)
ソースを読んで、文脈的にvcの型が合わないんだろうと思って*をつけたらうまく動いた。
14 *vc = vec_add(*va, *vb); // 1 + 2, 3 + 4, 5 + 6, 7 + 8
$ !gcc gcc -maltivec -mabi=altivec ex2-1.c -o ex2-1.elf $ ./ex2-1.elf c[0]=3, c[1]=7, c[2]=11, c[3]=15調子に乗って演習問題もやってみる。
演習問題 (2-1)
#include <stdio.h> #include <altivec.h> #define MAX_NUM 1024 int a[MAX_NUM] __attribute__((aligned(16))); int b[4] __attribute__((aligned(16))) = {0, 0, 0, 0}; int main(int argc, char *argv[]) { int i; vector signed int *va; vector signed int *vb = (vector signed int *) b; for (i = 0; i < MAX_NUM; i++) { a[i] = i + 1; } for (i = 0; i < MAX_NUM; i += 4) { va = (vector signed int *) (a + i); *vb = vec_add(*va, *vb); } printf("%d\n", b[0] + b[1] + b[2] + b[3]); return 0; }模範解答が載っていないのであっているかわからない。ひょっとしたら、出題者の意図としては、1024の配列ではなく4要素の配列を作って、ループの中で4つづつ中身を書き換えさせたいのかも知れないが、これでもまあ問題はないだろう。
1024の総和だと、SIMDを使わない場合と差が出なかったので、102400で試してみたところ、SIMDを使った方が遅かった(笑)。まあ、これは使い方を覚えるためのサンプルなので、そんなものだろう。
不思議なことに、SIMDを使ったほうはほぼuser time だけを消費し、SIMDを使わない方はほぼ sys time だけを消費した。
演習問題 (2-2)
#include <stdio.h> #include <altivec.h> #define SIZE (16) unsigned short in[SIZE] __attribute__((aligned(16))) = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; static unsigned short dummy[SIZE] __attribute__((aligned(16))); float out[SIZE] __attribute__((aligned(16))); int main(int argc, char *argv[]) { int i; vector unsigned short *va; vector unsigned short *vb = (vector unsigned short *)dummy; vector unsigned char vpat1 = (vector unsigned char) { 0x10, 0x10, 0x00, 0x01, 0x10, 0x10, 0x02, 0x03, 0x10, 0x10, 0x04, 0x05, 0x10, 0x10, 0x06, 0x07, }; vector unsigned char vpat2 = (vector unsigned char) { 0x10, 0x10, 0x08, 0x09, 0x10, 0x10, 0x0a, 0x0b, 0x10, 0x10, 0x0c, 0x0d, 0x10, 0x10, 0x0e, 0x0f, }; vector unsigned int vc; vector float *vd; va = (vector unsigned short *)in; vc = vec_perm(*va, *vb, vpat1); vd = (vector float *)out; *vd = vec_ctf(vc, 1); vc = vec_perm(*va, *vb, vpat2); vd = (vector float *)(out + 4); *vd = vec_ctf(vc, 1); va = (vector unsigned short *)(in + 8); vc = vec_perm(*va, *vb, vpat1); vd = (vector float *)(out + 8); *vd = vec_ctf(vc, 1); vc = vec_perm(*va, *vb, vpat2); vd = (vector float *)(out + 12); *vd = vec_ctf(vc, 1); for (i = 0; i < SIZE; i++) { printf("out[%02d]=%0.1f\n", i, out[i]); } return 0; }2-2は、最初出題プログラム2-2をコピーして始めたら、inとoutが16バイトアラインに並んでいなくてはまった。
後は、vector short と vector int の関係、メモリイメージ、vec_permの使い方が頭の中でリンクしなくて、結構はまってしまった。
長くなるので続きは次のエントリで。
カテゴリ
Linuxトラックバック(0)
このブログ記事を参照しているブログ一覧: CELLプログラミングその1
このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/1113
コメントする