我遇到了一个问题,在并行操作期间,我在某些机器上遇到了严重的性能问题。例如,下面的代码在2芯片机器上可以很好地扩展,每个芯片有8个内核,但在2芯片机器上的扩展性很差,每个芯片有10个内核。
探查器指示具有2x10核心的计算机的缓存未命中,并指示对Windows RtlEnterCriticalSection
的呼叫。这里的大部分时间花在malloc / free上。对于2x8核心机器,大部分时间花费在std::rand
上(裸矩阵矩阵产品只是为了引入一些虚拟数字运算)。
对于2x8核心机器,我根本没有得到任何缓存未命中,而且我也没有'看到对RtlEnterCriticalSection
的来电。相反,我看到调用RtlInterlockedPopSList
看起来像Windows正在使用原子来管理堆锁。问题是为什么它会使用另一台机器上的关键部分,这对于多线程效率非常低?
std::vector> futures;
for (auto iii = 0; iii != 40; iii++) {
futures.push_back(std::async([]() {
for (auto i = 0; i != 100000 / 40; i++) {
const int size = 10;
for (auto k = 0; k != size * size; k++) {
double* matrix1 = (double*)malloc(100 * sizeof(double));
double* matrix2 = (double*)malloc(100 * sizeof(double));
double* matrix3 = (double*)malloc(100 * sizeof(double));
for (auto i = 0; i != size; i++) {
for (auto j = 0; j != size; j++) {
matrix1[i * size + j] = std::rand() / RAND_MAX;
matrix2[i * size + j] = std::rand() / RAND_MAX;
}
}
for (auto i = 0; i != size; i++) {
for (auto j = 0; j != size; j++) {
double sum = 0.0;
for (auto k = 0; k != size; k++) {
sum += matrix1[i * size + k] * matrix2[k * size + j];
}
matrix3[i * size + j] = sum;
}
}
free(matrix1);
free(matrix2);
free(matrix3);
}
}
}));
}
for (auto& entry : futures)
entry.wait();