简体   繁体   中英

Fastest way to substitute the entries in a 2D Array with entries from 1D Arrat

I have a question here about entry sustitution. Let's say we have a matrix (squared) of a fixed size MATRIX_SIZE (unsorted 2D Array), a list of numbers replacementPolicy and another list of number substitudeNUMBER. We loop over the matrix, and if the entry has the same value as the (first) element in the replacementPolicy, we remember the position i, and substitude this entry with the i-th element in substitudeNUMBER. It sounds a little bit complicated, the code is as follows:

void substitute_entry() {
    // For each entry in the matrix
    for (int column = 0; column < MATRIX_SIZE; ++column) {
        for (int row = 0; row < MATRIX_SIZE; ++row) {
            // Search for the entry in the original number list
            // and replace it with corresponding the element in the substituted number list
            int index = -1;
            for (int i = 0; i < LIST_SIZE; i++) {
                if (replacementPolicy[i] == MATRIX[row][column]) {
                    index = i;
                }
            }

            MATRIX[row][column] = substitutedNUMBER[index];
        }
    }
}

However, I would expect to optimize this code in order to achieve a faster runtime. My first idea is to switch the for loop - first over columns and then over rows, but this does not affect the runtime significantly. My second thought is to use a better algorithm to replace the entries, but unfortunately I mess up when testing. Is there any better way to do so?

Thank you!

I think your loops are perfect for a multithreading solution, for example, using the OpenMP, and with its capabilities, you can expect a significant improvement in the performance. I've made a few changes to your code, as follows:

#include <iostream>
#include <chrono>
#include <omp.h>

#define MATRIX_SIZE 1000
#define LIST_SIZE 1000

int arr[MATRIX_SIZE][MATRIX_SIZE];
int replacementPolicy[LIST_SIZE];
int substitutedNUMBER[MATRIX_SIZE];

void substitute_entry() {
    // For each entry in the matrix
    #pragma omp parallel for
    for (int column = 0; column < MATRIX_SIZE; ++column) {
        #pragma omp parallel for
        for (int row = 0; row < MATRIX_SIZE; ++row) {
            // Search for the entry in the original number list
            // and replace it with corresponding the element in the substituted number list
            int index = -1;
            for (int i = 0; i < LIST_SIZE; i++) {
                if (replacementPolicy[i] == arr[row][column]) {
                    index = i;
                }
            }

            arr[row][column] = substitutedNUMBER[index];
        }
    }
}

int main()
{
  omp_set_num_threads(4);
  for ( int i = 0; i<MATRIX_SIZE ; i++)
  {
    replacementPolicy[i] = i;
    substitutedNUMBER[i] = i;

    for ( int j=0; j<MATRIX_SIZE ; j++) 
    {
      arr[i][j] = i+j;
    }
  }

  auto start = std::chrono::high_resolution_clock::now();
  substitute_entry();
  auto end = std::chrono::high_resolution_clock::now();
  uint64_t diff = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
  std::cerr << diff << '\n';
  return 0;
}

you can comment out the 3,14,16, and 34 lines and have the single thread version of your code. In this example with MATRIX_SIZE of 1000, and on my personal computer which has only four cores, the single thread version gets done in 3731737 us and the multithreaded version in 718039 us.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM