Speicherverlust in C ++ beim Ausführen von Verschiebungsoperationen in einer Schleife
Ich habe es geschafft, das Problem auf den folgenden Code zu reduzieren, der fast 500 MB Speicher benötigt, wenn er auf meinem Laptop ausgeführt wird - was wiederum ein std :: bad_alloc im vollständigen Programm verursacht. Was ist das Problem hier? Soweit ich sehen kann, verwendet die ungeordnete Karte nur so etwas wie (32 + 32) * 4096 * 4096 Bit = 134,2 MB, was nicht einmal dem entspricht, was das Programm verwendet.
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int,int> a;
long long z = 0;
for (int x = 0; x < 4096; x++)
{
for (int y = 0; y < 4096; y++)
{
z = 0;
for (int j = 0; j < 4; j++)
{
z ^= ((x>>(3*j))%8)<<(3*j);
z ^= ((y>>(3*j))%8)<<(3*j + 12);
}
a[z]++;
}
}
return 0;
}
EDIT: Ich bin mir bewusst, dass ein Teil der Bitverschiebung hier undefiniertes Verhalten verursachen kann, aber ich bin zu 99% sicher, dass dies nicht das Problem ist.
EDIT2: Was ich brauche, ist im Wesentlichen die Anzahl von x in einer gegebenen Menge zu zählen, die einige Funktionen jedem y in einer zweiten Menge (Größe 4096 * 4096) zuordnen. Wäre es besser, diese Zahlen vielleicht in einem Array zu speichern? Dh ich habe eine Funktion f: A bis B, und ich muss die Größe der Menge {x in A: f (x) = y} für jedes y in B kennen. In diesem Fall sind A und B beide die Menge von nicht negative ganze Zahlen kleiner als 2 ^ 12 = 4096. (Idealerweise möchte ich dies auf 2 ^ 32 erweitern).
... die fast 500 MB Speicher verbraucht ... Was ist hier das Problem?
An sich gibt es kein wirkliches Problem hinsichtlich der beobachteten Speichernutzung. std::unordered_map
wurde entwickelt, um für eine große Anzahl von Elementen schnell zu laufen. Speicher hat daher keine höchste Priorität. Um beispielsweise die Größenänderung zu optimieren, werden bei der Erstellung häufig einige vorberechnete Hash-Ketten zugewiesen . Außerdem berücksichtigt Ihr Maß für die Anzahl der Elemente multipliziert mit der Größe des Elements nicht den tatsächlichen Speicherbedarf in Bezug auf die Datenstruktur jedes Knotens in dieser Karte - was zumindest einige Zeiger auf benachbarte Elemente beinhalten sollte in der Liste seines Eimers .
Es ist jedoch nicht klar, ob Sie es std::unorderd_map
in diesem Szenario überhaupt verwenden müssen. In Anbetracht der Zuordnung ist Ihr versuchender Speicher stattdessen definiert als
{x in A: f (x) = y} für jedes y in B.
Sie könnten ein Array mit fester Größe haben (verwenden Sie es std::array
dafür), das einfach für jeden Index i
gilt und das Element in Satz B darstellt , die Anzahl der Elemente aus Satz A , die die Kriterien erfüllen.