如何在 <threads> c++ 中使用和一维数组进行矩阵乘法?
How to do a matrix multiplication using <threads> and a 1-D array in c++?
我正在尝试使用线程进行矩阵乘法。但是我没有正确的值。由于矩阵可能很大,因此我使用堆内存。因此,矩阵存储在1-D阵列中。
矩阵始终是一个方形矩阵,因此行的数量和列数等于阵列长度的平方根。如果数组长度为16,则行数为4,列的数量也为4。
我不能使用std::vector
,所以这就是为什么使用std::unique_ptr
。
有4个线程,每个线程都会收到可使用的原始数组的1/4。由于矩阵乘法的性质,这无效,我似乎找不到正确的解决方案。如何将4个线程的任务拆分?
auto matrixmultiplication(float* &array1, float* &array2, int arrayLength) {
unique_ptr<float[]> arrayOut(new float[arrayLength]);
auto numberOfThreads = 4;
auto widthMatrix = (int)sqrt(arrayLength);
auto elementsPerThread = (int)sqrt(arrayLength / numberOfThreads);
auto mul = [](auto* array1, auto* array2, auto* array3, auto dimension) {
for (auto x = 0; x < dimension; x++) {
for (auto y = 0; y < dimension; y++) {
array3[dimension * x + y] = 0;
for (auto z = 0; z < dimension; z++) {
array3[dimension * x + y] += array1[dimension * x + z] * array2[dimension * z + y];
}
}
}
};
vector<thread> threads;
for (auto i = 0; i < numberOfThreads; i++) {
threads.push_back(
thread(
mul,
array1 + i * elementsPerThread,
array2,
arrayOut.get() + i * elementsPerThread,
elementsPerThread
)
);
}
for (auto &thread : threads) {
thread.join();
}
return arrayOut;
};
对于所有线程,我将从第一个矩阵的连续行启动处理,即0th thread将处理0第0行,第1行将处理第1行,等等,等等到第nth线程。
线程处理一行后,必须通过线程数跳到下一行,即,如果我有2个线程,则在0th the -thone Processig第0行之后,它将跳到第二行并进行处理。
让我们在一个工作示例中查看:
#include <iostream>
#include <memory>
#include <vector>
#include <thread>
// multiplies the specified row and column from specified matrices
void multiply(const int* m_1, const int* m_2,
std::size_t size, std::size_t row, std::size_t col, int* m_res) {
for(std::size_t i = 0; i < size; ++i)
m_res[row * size + col] += m_1[row * size + i] * m_2[i * size + col];
}
int main() {
constexpr int N = 3, THREAD_NUM = 2;
// matrices to multiply and a matrix for result
std::unique_ptr<int[]> A(new int[N * N] {
11, 12, 13, 21, 22, 23, 31, 32, 33
});
std::unique_ptr<int[]> B(new int[N * N] {
1, 0, 0, 0, 1, 0, 0, 0, 1
});
std::unique_ptr<int[]> C(new int[N * N] {});
// create vector for running threads then assign threads to its elements
std::vector<std::thread> thread_group(THREAD_NUM);
for(int thread_i = 0; thread_i < THREAD_NUM; ++thread_i)
thread_group[thread_i] = std::thread([&, thread_i]() {
// each thread stars from consecutive rows then steps by
// the number of threads
for(int row = thread_i; row < N; row += THREAD_NUM) {
for(int col = 0; col < N; ++col)
multiply(A.get(), B.get(), N, row, col, C.get());
}
});
for(auto& t : thread_group)
t.join();
// show the result
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j)
std::cout << (j ? "t" : "") << C[i * N + j];
std::cout << std::endl;
}
}
如果您有两个要乘的矩阵,我们将其称为A
和B
,您只需要将矩阵A
行划分为4个零件,然后将零件传递到相应的线程中。当涉及矩阵B
时,您需要将对整个矩阵的引用传递给每个线程,因为您需要其所有元素来计算A*B
的每一行。这将是线程安全的,因为您将仅从矩阵B
读取而不将其读取。
相关文章:
- 将二维数组的所有元素插入到一维数组中
- C++语法差异:二维和一维数组(指针算术)
- 将一维数组写入 CSV C++中的不同列?
- C++:将矩阵存储在一维数组中
- 如何在一维数组中的每个元素中都有多个int值
- 以C++填充一维数组
- 用于在一维数组上嵌套循环操作的正确 openmp 指令
- 如何在 <threads> c++ 中使用和一维数组进行矩阵乘法?
- C++按内存地址将多维数组更改为一维数组
- 在 c++ 中返回一维数组时出错
- 一维数组映射方式的性能差异问题
- 如何使用一维数组更改二维数组中的值?
- 使用二维数组作为一维数组是否正确?可能会导致未定义的行为左右?
- 将一维数组转换为二维数组
- 如何使用一维数组列表初始化二维数组
- 在一维数组中对二维进行排序
- 将一维数组的索引转换为二维数组
- 通过访问二维数组实现双线性插值的概念类似于一维数组
- 将二维数组传递到只需要一维数组的函数中(C++)
- 如何访问带有多个括号的一维数组以提高可读性