源数据数组, 如 char a[640 * 480],
要将全部偶数项,即a[0],a[2],a[4]…a[640*480-2]复制到 char b[640*240]数组。
直接的方法是
要将全部偶数项,即a[0],a[2],a[4]…a[640*480-2]复制到 char b[640*240]数组。
直接的方法是
int i; int j = 0; for(i=0; i<640*480; i++) { if(i % 0 == 0) { b[j] = a[i]; j++; } }
由于是在嵌入式系统下运行,且一秒钟要做20~30次。负担太重了。
问一下各位有没有可以快速实现的方法?
谢谢
解决方案:5分
int i; int j = 0; for(i=0; i<640*480; i+=2,j++) { b[j] = a[i]; }
那个 求余算法是不必要的
解决方案:2分
int i; for(i = 0; i < 640 * 480; i +=2) { b[i / 2] = a[i]; }
其实j也是不必要的
解决方案:2分
for(i=0; i<640*480/2; i++) b[i] = a[i * 2];
乘以2的倍数的常数优化后会变成移位运算
解决方案:5分
int i; int j = 0; char * b[640*240] for(i=0; i<640*480; i+=2,j++) { b[j] = &a[i]; }
以后再也不用复制了
解决方案:10分
一般情况下,用最简洁易懂的方式写出的c代码,靠编译器优化往往比手工优化更有效。
以下面的代码为例:
以下面的代码为例:
// test1.c #include <stdio.h> #include <stdint.h> #include <time.h> #define GET_EVEN_BYTES(x1, x2) (x1 & 0xff) | (((x1 >> 16) & 0xff) << 8) | \ (((x2 & 0xff)) << 16) | (((x2 >> 16) & 0xff) << 24) static void func1(const char * a, size_t size, char * b) { uint32_t * p_a = (uint32_t *)a; uint32_t * p_end = (uint32_t *)(a + size); uint32_t * p_b = (uint32_t *)b; while(p_a < p_end) { *p_b++ = (uint32_t)GET_EVEN_BYTES(p_a[0], p_a[1]); p_a += 2; } } static void func2(const char * a, size_t size, char * b) { size_t i; size /= 2; for(i = 0; i < size; ++i) b[i] = a[i * 2]; } int main(int argc, char **argv) { size_t size; char a[640 * 480] = {0x11,0x22,0x33,0x44, 0x55, 0x66, 0x77, 0x88}; char b[640 * 240] = {0}; size = sizeof(a); clock_t t; int i; const int ROUNDS = 10000; t = clock(); for(i = 0; i < ROUNDS; ++i) { func1(a, size, b); } t = clock() - t; printf("func1 time: %f\n", (double)t / (double)CLOCKS_PER_SEC); t = clock(); for(i = 0; i < ROUNDS; ++i) { func2(a, size, b); } t = clock() - t; printf("func2 time: %f\n", (double)t / (double)CLOCKS_PER_SEC); for(i = 0; i < 16; ++i) { printf("%.2x ", b[i]); } printf("\n"); return 0; }
func1是用手工优化的方式来实现,将位运算的结果赋值给uint类型,这通常比直接逐字节赋值要快很多。
func2是用最简单易懂的方式来实现。
假如不通过编译器优化:
$ gcc -o test1 test1.c
$ ./test1
func1 time: 1.317621
func2 time: 4.110902
-O2 优化下:
$ gcc -O2 -o test1 test1.c
$ ./test1
func1 time: 0.688920
func2 time: 1.076817
此时,手工优化的代码(func1)均比简洁方式的代码(func2)快很多;但是,
-O6优化下,简洁方式的代码效率胜出了:
$ gcc -O6 -o test1 test1.c
$ ./test1
func1 time: 0.255404
func2 time: 0.207539
解决方案:2分
假如不需要存储的话,可以用#8的方法:
char a[640 * 480];
short *b = (short *)a;
之后直接用(char)b[xxx]来访问。
要存储的话可以考虑SSE指令,pshufb、packuswb之类的,假如你的架构支持的话。
char a[640 * 480];
short *b = (short *)a;
之后直接用(char)b[xxx]来访问。
要存储的话可以考虑SSE指令,pshufb、packuswb之类的,假如你的架构支持的话。
解决方案:2分
嵌入式的话可以看看芯片提供的接口,这种取值使用dma是最快的,现在很多图像处理的dsp都提供了这样的dma操作。
解决方案:2分
LZ说的是“源数据数组, 如 char a[640 * 480]”,大嘴你非要整成int/short…
解决方案:10分
最近本人好象眼睛里面揉进沙子了。
#include <stdio.h> char a[640*480]; char b[640*480/2]; void func1() { int i; int j = 0; for (i=0; i<640*480; i++) { if (i % 2 == 0) { b[j] = a[i]; j++; } } } void func2() { __asm { push esi push edi push ecx lea esi,a lea edi,b mov ecx,640*480/2 cld step1: lodsb stosb inc esi loop step1 pop ecx pop edi pop esi } } int main() { for (int i=0; i<640*480; i++) a[i]=(char)(i%100); func1(); printf("%d\n",b[640*480/2-1]); b[640*480/2-1]=0; func2(); printf("%d\n",b[640*480/2-1]); return 0; } //98 //98 //