我正在尝试使用open mp加速稀疏矩阵向量产品,代码如下:
void zAx(double * z, double * data, long * colind, long * row_ptr, double * x, int M){
long i, j, ckey;
int chunk = 1000;
//int * counts[8]={0};
#pragma omp parallel num_threads(8)
{
#pragma omp for private(ckey,j,i) schedule(static,chunk)
for (i=0; i<M; i++ ){
z[i]=0;
for (ckey=row_ptr[i]; ckey<row_ptr[i+1]; ckey++) {
j = colind[ckey];
z[i] += data[ckey]*x[j];
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这个代码运行正常,并产生正确的结果,但它只给我加速~30%.我已经检查过,线程都得到大约相同数量的非零元素(它们是),并且矩阵相当大(300,000 x 300,000),所以我希望开销不是唯一的问题.我也尝试使用不同的块大小和线程数运行,我得到了类似的性能.
还有什么我可以试着从中获得一点额外的速度吗?或者我显然做错了什么?
干杯.
编辑:刚刚注释掉'// int*counts [8] = {0}',因为它是计算工作分配的剩余部分.不需要
Edit2(更多细节):
好的,所以我定时拨打5000次循环并得到平均时间:
矩阵的大小为:303544x303544 …
我正在开始使用多线程编程,所以如果以下内容显而易见,请原谅.我正在为图像处理程序添加多线程,并且加速并不完全是我期望的.
我目前在具有超线程(4)的4个物理处理器CPU上获得4倍的加速,所以我想知道这种加速是否是预期的.我唯一能想到的是,如果单个物理CPU的两个超线程都必须共享某种内存总线,那么它可能是有意义的.
考虑到所有内存都分配在RAM中(我明白我的操作系统的虚拟内存管理器将决定是否进入页面,因此对于多线程来说,我不完全清楚这是否会被视为I/O绑定程序)这个假设的内存量来自堆)我的机器有16Gb的RAM,以防它决定分页/交换是否是一个问题.
我编写了一个测试程序,展示了使用QThreadPool和tbb :: parallel_for的串行案例和两个并行案例
您可以看到的当前程序除了将假定的图像从黑色设置为白色之外没有任何实际操作,并且它是为了在将任何实际操作应用于图像之前知道基线是什么而完成的.
我正在附加该程序,希望有人可以解释我,如果我在这种处理算法中寻求大约8倍的加速是一个失败的原因.请注意,我对其他类型的优化(例如SIMD)不感兴趣,因为我真正关心的不仅仅是让它更快,而是使用纯多线程使其更快,而不需要进入SSE或处理器缓存级别优化.
#include <iostream>
#include <sys/time.h>
#include <vector>
#include <QThreadPool>
#include "/usr/local/include/tbb/tbb.h"
#define LOG(x) (std::cout << x << std::endl)
struct col4
{
unsigned char r, g, b, a;
};
class QTileTask : public QRunnable
{
public:
void run()
{
for(uint32_t y = m_yStart; y < m_yEnd; y++)
{
int rowStart = y * m_width;
for(uint32_t x = m_xStart; x < m_xEnd; x++)
{
int index = rowStart + x;
m_pData[index].r = 255;
m_pData[index].g = …Run Code Online (Sandbox Code Playgroud)