Какое самое быстрое заполнение массива массива изображений

Поэтому у меня есть массив изображений в 1D:

a = {1,2,3,4,5,6,7,8,9}

Каков самый быстрый способ сделать массив, чтобы окружить его с помощью zeoes:

0 0 0 0 0
0 1 2 3 0
0 4 5 6 0
0 7 8 9 0
0 0 0 0 0

Я уже объявил массив b (который является массивом заполнения):

float *b = calloc(((data_size_X + 2)*(data_size_Y +2)), sizeof(float));
2 ответа

Вот некоторые бенчмаркинга. Моя догадка была правильной - использование memcpy значительно быстрее, чем альтернативы:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
 char* original;
 char* padded;
 long int n, m, ii, jj, kk;
 time_t startT, stopT;

 char *p1, *o1; // point to first element in row for padded, original

 // pick a reasonably sized image:
 n = 3000;
 m = 2000;

 // allocate memory:
 original = malloc(m * n * sizeof(char));
 padded = calloc((m+2)*(n+2), sizeof(char));

 // put some random values in it:
 for(ii = 0; ii < n*m; ii++) {
 original[ii] = rand()%256;
 }

 // first attempt: completely naive loop
 startT = clock();
 for(kk = 0; kk < 100; kk++) {
 for(ii = 0; ii < m; ii++) {
 for(jj = 0; jj < n; jj++) {
 padded[(ii + 1) * (n + 2) + jj + 1] = original[ ii * n + jj];
 }
 }
 }
 stopT = clock();
 printf("100 loops of 'really slow' took %.3f ms\n", (stopT - startT) * 1000.0 / CLOCKS_PER_SEC);

 // second attempt - pre-compute the index offset
 startT = clock();
 for(kk = 0; kk < 100; kk++) {
 for(ii = 0; ii < m; ii++) {
 p1 = padded + (ii + 1) * (n + 2) + 1;
 o1 = original + ii * n;
 for(jj = 0; jj < n; jj++) {
 p1[jj] = o1[jj];
 }
 }
 }
 stopT = clock();
 printf("100 loops of 'not so fast' took %.3f ms\n", (stopT - startT) * 1000.0 / CLOCKS_PER_SEC);

 // third attempt: use memcpy to speed up the process 
 startT = clock();
 for(kk = 0; kk < 100; kk++) {
 for(ii = 0; ii < m; ii++) {
 p1 = padded + (ii + 1) * (n + 2) + 1;
 o1 = original + ii * n;
 memcpy(p1, o1, n);
 }
 }
 stopT = clock();
 printf("100 loops of 'fast' took %.3f ms\n", (stopT - startT) * 1000.0 / CLOCKS_PER_SEC);

 free(original);
 free(padded);
 return 0;
}
</time.h></stdlib.h></string.h></stdio.h>

Вот результат:

100 loops of 'really slow' took 3020.585 ms
100 loops of 'not so fast' took 3725.056 ms
100 loops of 'fast' took 332.298 ms

Когда я включил оптимизацию компилятора с помощью -O3, время изменилось следующим образом:

100 loops of 'really slow' took 2727.442 ms
100 loops of 'not so fast' took 488.244 ms
100 loops of 'fast' took 326.998 ms

Очевидно, что компилятор "заметил" чистую копию цикла и попытался ее оптимизировать несколько, но он все равно не так хорошо, как memcpy. И в memcpy практически не осталось оптимизма.


Если вы уже выделили b как описано, следующее, вероятно, будет быстрее, чем вложенные для циклов:

int aIndex;
int maxA = data_size_X * data_size_Y;
float * pb = b + data_size_X + 3;
memset(b, 0, (data_size_X + 2) * (data_size_Y + 2) * sizeof(float));
for (aIndex = 0; aIndex < maxA; aIndex += data_sizeX) {
 memcpy(pb, a + aIndex, data_size_X);
 pb += (data_size_X + 2);
}

licensed under cc by-sa 3.0 with attribution.