MPL検証
をテンプレートにして作成
Check
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
*C++テンプレートメタプログラミングの検証 [#of1fd78a]
**処理速度について [#c66ff7e2]
テンプレートメタプログラミングの非常に魅力的なところは、...
ここでは、テンプレートも含めて、従来の手法とテンプレート...
***Imageライブラリにおいてのパフォーマンス向上策(その1) [...
RGB24bitや、8bitグレイスケールなど、様々な画像形式のイメ...
ColorRGBA getPixel(int x, int y);
void setPixel(int x, int y, ColorRGBA col);
ColorRGBAは、以下のような実装になっています。
struct ColorRGBA {
union {
uint32_t rgba;
struct {
uint32_t r:8;
uint32_t g:8;
uint32_t b:8;
uint32_t a:8;
};
};
};
つまり、ColorRGBAは、32bitの整数を8bit毎のR,G,B,Aでアクセ...
RGB24bitの場合は、R,G,Bのみを、グレイスケールの場合はRの...
さて、何も考えずにとりあえずクラスを作ってみましょう。
struct ImageBuffer {
virtual ColorRGBA getPixel(int x, int y) const = 0;
virtual void setPixel(int x, int y, ColorRGBA col) = 0;
int width_;
int height_;
};
struct ImageBufferRGBA : ImageBuffer {
ColorRGBA getPixel(int x, int y) const {
return buffer32[x + y * width_];
}
void setPixel(int x, int y, ColorRGBA col) {
buffer32[x + y * width_] = col.rgba;
}
uint32_t* buffer32;
};
struct ImageBufferRGB : ImageBuffer {
ColorRGBA getPixel(int x, int y) const {
ColorRGBA col;
col.r = buffer8[(x + y * width_)*3];
col.g = buffer8[(x + y * width_)*3+1];
col.b = buffer8[(x + y * width_)*3+2];
return col;
}
void setPixel(int x, int y, ColorRGBA col) {
buffer8[(x + y * width_)*3] = col.r;
buffer8[(x + y * width_)*3+1] = col.g;
buffer8[(x + y * width_)*3+2] = col.b;
}
uint8_t* buffer8;
};
ご覧のとおり、R,G,B,Aの32bitを扱うイメージは、uint32_t型...
&br;
さて、ここで任意のImageBufferから任意のImageBufferへ、ピ...
void copy(ImageBuffer* dest, const ImageBuffer* src) {
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
こんな感じでしょうか。(バッファのメモリ確保は省略していま...
さて、ここで素朴が疑問がひとつ。ImageBufferのsetPixel/get...
関数コールのアドレスをルックアップする手順が増えるわけで...
テンプレートを使わないでも解決策はあります。C++は引数の型...
void copy(ImageBufferRGBA* dest, const ImageBufferRGBA* ...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGB* dest, const ImageBufferRGB* sr...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGBA* dest, const ImageBufferRGB* s...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGB* dest, const ImageBufferRGBA* s...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
これでOK。コピペすれば簡単ですし、#defineでマクロにするの...
しかし、これには問題があります。そう、ImageBufferXXXXXの...
template <class DEST, class SRC>
void copy(DEST* dest, const SRC* src) {
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
これならコピペも#define不要で、virtualコールも起こらずに...
つづく
#back
終了行:
*C++テンプレートメタプログラミングの検証 [#of1fd78a]
**処理速度について [#c66ff7e2]
テンプレートメタプログラミングの非常に魅力的なところは、...
ここでは、テンプレートも含めて、従来の手法とテンプレート...
***Imageライブラリにおいてのパフォーマンス向上策(その1) [...
RGB24bitや、8bitグレイスケールなど、様々な画像形式のイメ...
ColorRGBA getPixel(int x, int y);
void setPixel(int x, int y, ColorRGBA col);
ColorRGBAは、以下のような実装になっています。
struct ColorRGBA {
union {
uint32_t rgba;
struct {
uint32_t r:8;
uint32_t g:8;
uint32_t b:8;
uint32_t a:8;
};
};
};
つまり、ColorRGBAは、32bitの整数を8bit毎のR,G,B,Aでアクセ...
RGB24bitの場合は、R,G,Bのみを、グレイスケールの場合はRの...
さて、何も考えずにとりあえずクラスを作ってみましょう。
struct ImageBuffer {
virtual ColorRGBA getPixel(int x, int y) const = 0;
virtual void setPixel(int x, int y, ColorRGBA col) = 0;
int width_;
int height_;
};
struct ImageBufferRGBA : ImageBuffer {
ColorRGBA getPixel(int x, int y) const {
return buffer32[x + y * width_];
}
void setPixel(int x, int y, ColorRGBA col) {
buffer32[x + y * width_] = col.rgba;
}
uint32_t* buffer32;
};
struct ImageBufferRGB : ImageBuffer {
ColorRGBA getPixel(int x, int y) const {
ColorRGBA col;
col.r = buffer8[(x + y * width_)*3];
col.g = buffer8[(x + y * width_)*3+1];
col.b = buffer8[(x + y * width_)*3+2];
return col;
}
void setPixel(int x, int y, ColorRGBA col) {
buffer8[(x + y * width_)*3] = col.r;
buffer8[(x + y * width_)*3+1] = col.g;
buffer8[(x + y * width_)*3+2] = col.b;
}
uint8_t* buffer8;
};
ご覧のとおり、R,G,B,Aの32bitを扱うイメージは、uint32_t型...
&br;
さて、ここで任意のImageBufferから任意のImageBufferへ、ピ...
void copy(ImageBuffer* dest, const ImageBuffer* src) {
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
こんな感じでしょうか。(バッファのメモリ確保は省略していま...
さて、ここで素朴が疑問がひとつ。ImageBufferのsetPixel/get...
関数コールのアドレスをルックアップする手順が増えるわけで...
テンプレートを使わないでも解決策はあります。C++は引数の型...
void copy(ImageBufferRGBA* dest, const ImageBufferRGBA* ...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGB* dest, const ImageBufferRGB* sr...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGBA* dest, const ImageBufferRGB* s...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
void copy(ImageBufferRGB* dest, const ImageBufferRGBA* s...
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
これでOK。コピペすれば簡単ですし、#defineでマクロにするの...
しかし、これには問題があります。そう、ImageBufferXXXXXの...
template <class DEST, class SRC>
void copy(DEST* dest, const SRC* src) {
for (int y= 0; y < src->height_; ++y) {
for (int x = 0; x < src->width_; ++x) {
dest->setPixel(x, y, src->getPixel(x,y));
}
}
}
これならコピペも#define不要で、virtualコールも起こらずに...
つづく
#back
ページ名: