[英]Fastest way to substitute the entries in a 2D Array with entries from 1D Arrat
我在这里有一个关于条目替代的问题。 假设我们有一个固定大小的矩阵(平方) MATRIX_SIZE(未排序的二维数组)、一个数字列表 replacementPolicy 和另一个数字 substitudeNUMBER 列表。 我们遍历矩阵,如果该条目与 replacementPolicy 中的(第一个)元素具有相同的值,我们记住 position i,并用 substitudeNUMBER 中的第 i 个元素替换该条目。 听起来有点复杂,代码如下:
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];
}
}
}
但是,我希望优化此代码以实现更快的运行时。 我的第一个想法是切换 for 循环 - 首先是列,然后是行,但这不会显着影响运行时。 我的第二个想法是使用更好的算法来替换条目,但不幸的是我在测试时搞砸了。 有没有更好的方法呢?
谢谢!
我认为您的循环非常适合多线程解决方案,例如,使用 OpenMP,并且凭借其功能,您可以期待性能显着提高。 我对您的代码进行了一些更改,如下所示:
#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;
}
您可以注释掉 3、14、16 和 34 行,并拥有代码的单线程版本。 在这个 MATRIX_SIZE 为 1000 的示例中,在我只有四个内核的个人计算机上,单线程版本在 3731737 us 完成,多线程版本在 718039 us 完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.