我有一小段代码可以执行以下操作:
我在同一个numa节点上的8个物理cpus上运行程序。但是对于大小为5M的hashT(即其中有5M ints),我只获得了x7.2的加速。我改变了hashT的大小,看到当它很小时,我得到x7.9加速,但随着它变得越来越大并且在某些时候(当阵列中有3M整数时),加速开始下降。我有一个200GB的RAM,所以内存应该不是问题。我还测量了内存带宽,而且我还没有接近最大可用带宽的一半。所以我认为这可能是由于缓存的争用。我有一个20MB的三级缓存,由所有线程共享。但是我测量了L2和L3缓存缺失,我发现无论我使用多少线程它们几乎都是一样的(确实增加hashT的大小会导致更多的缓存未命中)。所以我没有看到加速下降的原因。任何人都可以给我一个想法吗?
#include<iostream>
#include<vector>
#include<chrono>
#include<omp.h>
#include<stdio.h>
using namespace std;
typedef std::chrono::milliseconds ms;
struct Element{
int a, b, c;
Element() : a(0), b(1), c(2) {}
Element(int aa, int bb, int cc) : a(aa), b(bb), c(cc) {}
};
int main(int argc, char *argv[]){
int HASHT_SIZE = atoi(argv[1]);
int RID_SIZE = 5000000;
auto start = std::chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
vector<vector<Element> > vec1(40);
for(size_t i = 0; i < vec1.size(); i++){
vec1[i].reserve(RID_SIZE);
for(size_t j = 0; j < vec1[i].capacity(); j++){
vec1[i].push_back(Element(rand() % HASHT_SIZE,0,0));
}
}
//initialize hashT
vector<int> hashT;
hashT.reserve(HASHT_SIZE);
for(int i = 0; i < HASHT_SIZE; i++){
hashT.push_back(rand() % 2);
}
start = std::chrono::high_resolution_clock::now();
//test program
#pragma omp parallel for schedule(dynamic)
for(int j = 0; j < 40; j++)
{
for(size_t i = 0; i < RID_SIZE; i++){
int nid = hashT[vec1[j][i].a];
for(int k = 0; k < 10; k++){
vec1[j][i].b += nid / (k+1);
vec1[j][i].c += nid / (k+1);
}
}
}
end = std::chrono::high_resolution_clock::now();
for(int i = 0; i < 40; i++){
for(int j = 0; j < 10; j++){
cout << vec1[i][j].a << vec1[i][j].b << vec1[i][j].c;
}
}cout << endl;
cout << "Time used: " << std::chrono::duration_cast<ms>(end - start).count() << endl;
return 0;
}