本サイトは、マルチコア トータルソリューションカンパニー -フィックスターズの技術者有志が運営するサイトです。

3.9 演習問題 (3-4) グレースケール変換プログラム (単一SPE版)

出典: PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう

 演習問題 (3-4) は、第3章で学習した内容全体の理解度を確認するための総合問題です。

【問題】

 出題プログラム (3-4) は、演習問題 (2-4)で出題したグレースケール変換プログラムの解答です。ここに掲載されているrgb2y()関数は、VMX命令を利用してカラー画像のグレースケール変換をおこなう関数です。この関数の処理を1基のSPE上で実行するように、グレースケール変換プログラムを書き換えなさい。


【出題プログラム (3-4)】 (一部抜粋)

 1 #include <stdio.h>
 2 #include <altivec.h>
 3
 4 void rgb2y(unsigned char *src, unsigned char *dst, int num)
 5 {
 6     int i;
 7
 8     vector unsigned char *vsrc = (vector unsigned char *) src;
 9     vector unsigned char *vdst = (vector unsigned char *) dst;
10
11     vector unsigned int vr, vg, vb, vy, vpat;
12     vector float vfr, vfg, vfb, vfy;
13
14     vector float vrconst = (vector float) { 0.29891f, 0.29891f, 0.29891f, 0.29891f };
15     vector float vgconst = (vector float) { 0.58661f, 0.58661f, 0.58661f, 0.58661f };
16     vector float vbconst = (vector float) { 0.11448f, 0.11448f, 0.11448f, 0.11448f };
17     vector float vfzero  = (vector float) { 0.0f, 0.0f, 0.0f, 0.0f };
18     vector unsigned int vmax = (vector unsigned int) { 255, 255, 255, 255 };
19
20     vector unsigned char vpatr = (vector unsigned char) { 0x10, 0x10, 0x10, 0x00,
21                                                           0x10, 0x10, 0x10, 0x04,
22                                                           0x10, 0x10, 0x10, 0x08,
23                                                           0x10, 0x10, 0x10, 0x0c };
24     vector unsigned char vpatg = (vector unsigned char) { 0x10, 0x10, 0x10, 0x01,
25                                                           0x10, 0x10, 0x10, 0x05,
26                                                           0x10, 0x10, 0x10, 0x09,
27                                                           0x10, 0x10, 0x10, 0x0d };
28     vector unsigned char vpatb = (vector unsigned char) { 0x10, 0x10, 0x10, 0x02,
29                                                           0x10, 0x10, 0x10, 0x06,
30                                                           0x10, 0x10, 0x10, 0x0a,
31                                                           0x10, 0x10, 0x10, 0x0e };
32     vector unsigned char vpaty = (vector unsigned char) { 0x03, 0x03, 0x03, 0x10,
33                                                           0x07, 0x07, 0x07, 0x10,
34                                                           0x0b, 0x0b, 0x0b, 0x10,
35                                                           0x0f, 0x0f, 0x0f, 0x10 };
36     vector unsigned char vzero = (vector unsigned char) { 0, 0, 0, 0, 0, 0, 0, 0,
37                                                           0, 0, 0, 0, 0, 0, 0, 0 };
38
39     for (i = 0; i < num/4; i++) {
40         vr = (vector unsigned int) vec_perm(vsrc[i], vzero, vpatr);
41         vg = (vector unsigned int) vec_perm(vsrc[i], vzero, vpatg);
42         vb = (vector unsigned int) vec_perm(vsrc[i], vzero, vpatb);
43
44         vfr = vec_ctf(vr, 0);
45         vfg = vec_ctf(vg, 0);
46         vfb = vec_ctf(vb, 0);
47
48         vfy = vec_madd(vfr, vrconst, vfzero);
49         vfy = vec_madd(vfg, vgconst, vfy);
50         vfy = vec_madd(vfb, vbconst, vfy);
51
52         vy = vec_ctu(vfy, 0);
53
54         vpat = vec_cmpgt(vy, vmax);
55         vy = vec_sel(vy, vmax, vpat);
56
57         vdst[i] = (vector unsigned char) vec_perm(vy, (vector unsigned int) vzero, vpaty);
58     }
59
60     return;
61 }

⇒出題プログラム (3-4) のソースコードはこちらから


【解答方針】

 SPEプログラムの実行方法やSIMD演算の書き換えについては、第3章の学習内容を参考にしてください。

 この問題では、SPEプログラムで処理する画像データを、どのようにメインメモリとLSとの間で転送するかがポイントになります。DMA転送されるデータサイズや、DMA転送するアドレスのアラインメントなどに注意して作成してください。

 特に、1度のDMA転送で転送できるデータの最大サイズに注意をしてプログラミングをする必要があります。



表示
個人用ツール
オープンソースプロジェクト
ツールボックス