 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mario Lüttich Guest
|
Posted: Fri Oct 28, 2005 1:27 pm Post subject: for loop sehr langsam?? |
|
|
Hi Leute,
ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
als
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
..
Warum??? Wäre super wenn das einer wüste!
Grüsse
Mario
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Peter Schaefer Guest
|
Posted: Fri Oct 28, 2005 6:44 pm Post subject: Re: for loop sehr langsam?? |
|
|
Am 28.10.2005 15:27, Mario Lüttich wrote:
| Quote: | ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
als
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
.
Warum??? Wäre super wenn das einer wüste!
|
Kann nur vermuten: Im ersten Fall wird tmp ja nicht wirklich verwendet
(irgendwo zugewiesen). Daher denke ich, der Compiler optimiert einfach
die innere Schleife weg (wenn er so clever ist).
Gruß
Peter
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Moll Guest
|
Posted: Fri Oct 28, 2005 7:24 pm Post subject: Re: for loop sehr langsam?? |
|
|
Hallo
Mario Lüttich wrote:
| Quote: | ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
|
[Vergleichscode gesnippt]
Freu dich. Dein Compiler findet wohl für dich heraus, daß die inneren beiden
Schleifen nix tun und schmeißt sie weg.
Gruß
Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Spiro Trikaliotis Guest
|
Posted: Mon Oct 31, 2005 8:31 am Post subject: OT: Re: for loop sehr langsam?? |
|
|
Hallo Mario,
Mario Lüttich <mluetti (AT) gwdg (DOT) de> schrieb:
| Quote: | Hi Leute,
ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
[...]
als
[...]
Warum??? Wäre super wenn das einer wüste!
|
Ich könnte wie die anderen in meine Kristallkugel und sagen, wieso das
wahrscheinlich so ist - die sicherste Variante wäre allerdings, sich den
generierten Assembler-Code anzuschauen, dann weißt du mit Sicherheit,
was passiert.
Meine Kristallkugel hat 2 Erklärungen:
1. Der Compiler ist intelligent und stellt fest, dass tmp nicht benutzt
wird, womit die Schleifen wegoptimiert werden;
2. Du gehst durch die Arrays ziemlich "wahllos" durch. Bei 2000x2000-Arrays
(zum Abspeichern) gehst du da also durch 4M x "Datengröße" von data2d durch.
Hier lohnt es sich eventuell schon, sich um das "Thrashing" beim Paging zu
kümmern. Es gibt Algorithmen mit einer deutlich größeren "Lokalität" beim
Zugriff.
Falls tmp_mat() selbst auch wieder auf Arrays zugreift ist dort das Problem
bei einem 9000x2000-Array natürlich noch größer!
Ob sich der Aufwand zur Optimierung hier allerdings lohnt ist eine andere
Frage.
Natürlich kann auch beides der Fall sein.
Übrigens:
Ist die Zeile
tmp += tmp_mat(k,i) * tmp_mat(k,j);
wirklich richtig? Deine Funktion sieht mir nach Matrizen-Multiplikation aus,
aber da muss einer der beiden Indizes "umgedreht" werden.
Aber irgendwie ist das alles IMHO off-topic hier. Da ich zu faul zum Suchen der
passenden NG bin, fup2 poster.
Gruß,
Spiro.
--
Spiro R. Trikaliotis http://cbm4win.sf.net/
http://www.trikaliotis.net/ http://www.viceteam.org/
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Mario Lüttich Guest
|
Posted: Mon Oct 31, 2005 8:35 am Post subject: Re: for loop sehr langsam?? |
|
|
Peter Schaefer wrote:
| Quote: | Am 28.10.2005 15:27, Mario Lüttich wrote:
ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
als
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
.
Warum??? Wäre super wenn das einer wüste!
Kann nur vermuten: Im ersten Fall wird tmp ja nicht wirklich verwendet
(irgendwo zugewiesen). Daher denke ich, der Compiler optimiert einfach
die innere Schleife weg (wenn er so clever ist).
Gruß
Peter
Danke das könnte es sein. Jedoch ist das die Covarianze |
Matrixberechnung, und Matlab dauert das 90 Sekunden. In c++ (mit den
gepostetet Code) 30 Minuten?
Keine Ahnung was da falsch läuft.
Danke nochmal.
Gruss
Mario
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Olaf Krzikalla Guest
|
Posted: Mon Oct 31, 2005 2:19 pm Post subject: Re: for loop sehr langsam?? |
|
|
Hi,
Mario Lüttich wrote:
| Quote: | Danke das könnte es sein. Jedoch ist das die Covarianze
Matrixberechnung, und Matlab dauert das 90 Sekunden. In c++ (mit den
gepostetet Code) 30 Minuten?
Keine Ahnung was da falsch läuft.
Eventuell der Vergleich von Äpfeln und Birnen. Was tmp_mat macht, weiß |
hier keiner. Und die zweitausend cout-Ausgaben werden schon eine Menge
Zeit in Anspruch nehmen.
MfG
Olaf Krzikalla
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Hendrik Belitz Guest
|
Posted: Tue Nov 01, 2005 3:02 pm Post subject: Re: for loop sehr langsam?? |
|
|
Mario Lüttich wrote:
| Quote: | Danke das könnte es sein. Jedoch ist das die Covarianze
Matrixberechnung, und Matlab dauert das 90 Sekunden. In c++ (mit den
gepostetet Code) 30 Minuten?
|
Das dürfte daran liegen, daß Dein Code dank der Einführung des data2d-Arrays
selbst auf der höchsten Optimierungsstufe jede Menge Cache Misses
produzieren wird. Außerdem stellt sich die Frage, ob Du auch
architekturspezifisch optimiert hast. Das bringt in der Regeln nochmal
einen gewaltigen Leistungsschub, den Matlab sicher ausnutzt.
--
- Abort, Retry, Fthagn? -
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Dirk Clemens Guest
|
Posted: Tue Nov 01, 2005 5:20 pm Post subject: Re: for loop sehr langsam?? |
|
|
Mario Lüttich wrote:
| Quote: | Peter Schaefer wrote:
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
Danke das könnte es sein. Jedoch ist das die Covarianze
Matrixberechnung, und Matlab dauert das 90 Sekunden. In c++ (mit den
gepostetet Code) 30 Minuten?
Keine Ahnung was da falsch läuft.
|
Ist tmp_mat() deterministisch?
Falls ja: hast Du dir schon einmal übnerlegt, wie häufig
tmp_mat() mit identischen Parametern aufgerufen wird?
Und wie überhaupt sieht tmp_mat() aus?
Lemmi
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Wed Nov 02, 2005 11:48 am Post subject: Re: for loop sehr langsam?? |
|
|
Mario Lüttich wrote:
| Quote: |
Hi Leute,
ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
als
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
.
Warum??? Wäre super wenn das einer wüste!
|
Lass mich raten:
Dein erster Code-Abschnitt rechnet still und heimlich vor sich hin,
waehrend im zweite Code-Abschnitt die Festplatte wie verrueckt vor
sich hinroedelt?
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Ulrich Elsner Guest
|
Posted: Wed Nov 02, 2005 9:20 pm Post subject: Re: for loop sehr langsam?? |
|
|
Mario Lüttich <mluetti (AT) gwdg (DOT) de> writes:
| Quote: | ich habe da ein grossen Problem. Der Folge Code ist 100 mal schneller
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
tmp = 0.;
}
cout << "J: " << i << endl;
}
als
float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
tmp = 0.;
}
cout << "J: " << i << endl;
}
.
Warum??? Wäre super wenn das einer wüste!
|
Ist zwar kein C++ Problem, aber:
Ich würde mal auf Cache-Probleme tippen. Die problematische Zeile
vertreibt u.U. anderweitig wiederverwendbare Daten aus dem Cache.
Allerdings ist das ganze eh fürchterlich Cache-unfreundlich
implementiert. Wenn du es selber schreiben möchtest, solltest
du versuchen, die Matrixzugriffe Blockweise vorzunehmen.
Wenn das ganze bloss schnell gehen soll, verwende doch am besten
SSYMM (wenn ich das richtig sehe) einer optimierte BLAS Version
(z.B. ATLAS, http://math-atlas.sourceforge.net/)
Da sollte locker noch mal ein 10 facher Speedup mit drin sein.
Ulrich
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Oliver S. Guest
|
Posted: Sat Nov 05, 2005 11:58 pm Post subject: Re: for loop sehr langsam?? |
|
|
| Quote: | Das dürfte daran liegen, daß Dein Code dank der Einführung des
data2d-Arrays selbst auf der höchsten Optimierungsstufe jede Menge
Cache Misses produzieren wird. Außerdem stellt sich die Frage, ob
Du auch architekturspezifisch optimiert hast.
|
Wenn man einen Fall hat in dem Cache-Misses die "Performance"
dominieren, dann wird das auch nicht durch architektur-spezifi-
sche Optimierungen relativiert.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Oliver S. Guest
|
Posted: Sun Nov 06, 2005 12:00 am Post subject: Re: for loop sehr langsam?? |
|
|
| Quote: | Allerdings ist das ganze eh fürchterlich Cache-unfreundlich
implementiert. Wenn du es selber schreiben möchtest, solltest
du versuchen, die Matrixzugriffe Blockweise vorzunehmen.
|
Vorausgesetzt man weiß wie die Caches arbeiten.
Ansonsten sollte Mario sich erstmal damit beschäftigen.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Ulrich Elsner Guest
|
Posted: Sun Nov 06, 2005 10:29 am Post subject: Re: for loop sehr langsam?? |
|
|
"Oliver S." <Follow.Me (AT) gmx (DOT) net> writes:
| Quote: | Das dürfte daran liegen, daß Dein Code dank der Einführung des
data2d-Arrays selbst auf der höchsten Optimierungsstufe jede Menge
Cache Misses produzieren wird. Außerdem stellt sich die Frage, ob
Du auch architekturspezifisch optimiert hast.
Wenn man einen Fall hat in dem Cache-Misses die "Performance"
dominieren, dann wird das auch nicht durch architektur-spezifi-
sche Optimierungen relativiert.
|
Kommt darauf an, wie man optimiert: einfach nur einen Compiler-Switch
setzen, wird nicht helfen. Wenn man aber den Code selber auf die
Architektur anpasst, bringt das ungeheuer viel. In diesem Fall
ist in den optimierten BLAS-Bibiliotheken, die Matlab einsetzt,
der Algorithmus geblockt implementiert und die Blockgröße wird so
gewählt, dass gerade keine Cache-Misses auftreten.
Matrix-Matrix Operationen gehören zu den Operationen, in denen beim
wissenschaftlichen Rechnen die meiste Rechenzeit verbraten wird.
Unter anderem deswegen liefern z.B. die Prozessorhersteller
eigene Bibiliotheken dazu aus:
<http://www.intel.com/cd/software/products/asmo-na/eng/perflib/mkl/index.htm>
<http://developer.amd.com/acml.aspx>
Wenn man sich das FORTRAN Interface der BLAS nicht antun möchte, gibt
es auch C++ Wrapper dazu. Ich weiss allerdings nicht, wie gut die sind.
Ulrich
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Oliver S. Guest
|
Posted: Sun Nov 06, 2005 2:37 pm Post subject: Re: for loop sehr langsam?? |
|
|
| Quote: | Wenn man einen Fall hat in dem Cache-Misses die "Performance"
dominieren, dann wird das auch nicht durch architektur-spezifi-
sche Optimierungen relativiert.
Kommt darauf an, wie man optimiert: einfach nur einen
Compiler-Switch setzen, wird nicht helfen.
|
Ebent! Kein Compiler ändert die Zugriffs-Muster auf den Speicher
so daß das Problem durch einen Compiler-Switch gelöst werden könnte.
| Quote: | Wenn man aber den Code selber auf die Architektur anpasst, bringt
das ungeheuer viel.
|
Wenn es um Cache-Optimierungen geht, dann sind diese aber nicht wirklich
Architektur-spezifisch, sondern funktionieren meistens auf allen Architek-
turen mit Cache gut weil diese sich nur quantitativ unterscheiden, also
in Bezug auf Größe(n), Ebenenen und Assoziativität.
Ich hatte jedoch mal einen Fall in dem die quantitative Berücksichtigung
aller drei Kriterien ausschlaggebend war! Und zwar hatte ich mal einen
Inline-Patch (Patch auf das vorhandene Binary, also eher eine Art Crack)
für das damalige SETI@home 1.06 geschrieben; der führte dazu, daß sich
die Performance des Clients auf fast allen damalig verbreiteten Systemen
ungefähr verdoppelte. Die Optimierungen bestanden darin, die Reihenfolge
der Rechenoperationen in der FFT die den größten Anteil an der Rechenzeit
des SETI@home-Clients ausmacht so umzusortiern, daß die Lokalität auf
verschiedenen Zeitlichen Ebenen (temporal locality) und räumlichen Ebenen
(temporal locality) möglichs Cache-freundlich ist; das gilt für viele an-
dere Algorithmen auch, aber bei FFTs ist das *das* entscheidene Kriterium
für die Performance auf cachenden Architekturen. Ich habe damals übrigens
nix neues erfunden, sondern diese Gelegenheit gesehen als mit im Binary
des Clients aufgefallen war, daß die Leute aus Berkeley den FFT-Algorih-
mus aus dem "Numerical Recipes in C" verwendet (!) hatten und dieser bzgl
der Optimierung Potiential in zwei Richtungen hat. Eine ist die Optimie-
rung der Cache-lokalität und die andere die Optimierung des Rechenferfah-
rens. Erstere habe ich ja erwähnt, aber letztere wird in allen performan-
ten FFT-Librariess auch umgesetzt. Und zwar wird in diesen statt einer
primitiven "Radix-2-FFT" eine "Spilt-Radix-FFT" verwendet. Das ist aber
auch das einzige was ich über diese Optimierungs-Richtung in der Lage
zu verstehen war, denn ich bin kein Mathematiker und verstehe daher nicht
den Unterschied zwischen diesen beiden Rechenwegen. Interessanterweise
war "meine" Optimierung (ich hab sie zwar unabhängig gefunden, aber vor
mir gab es schon Millionen anderer Entwickler die die selbe Entdeckung
gemacht haben) aber in der Lage, sehr nahe an eine FFT heranzukommen die
beiden Optimerungen verwendet, d.h. der technische Aspekt ist in diesem
Fall deutlich wichtiger als der mathematische. Das fand ich in Anbetracht
der Tatsache, daß ich wenig Ahnung von Mathematik habe (obwohl ich im Abi
Mathe als LK hatte) sehr tröstlich. *g*
| Quote: | Matrix-Matrix Operationen gehören zu den Operationen, in denen beim
wissenschaftlichen Rechnen die meiste Rechenzeit verbraten wird.
Unter anderem deswegen liefern z.B. die Prozessorhersteller
eigene Bibiliotheken dazu aus:
|
Machen denn in diesem Fall auch die genannten "quantitativen"
Optimierungen Sinn?
(FUp & XPost auf de.comp.lang.misc weil das zu C++-unspezifisch wird)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Becker Guest
|
Posted: Tue Nov 08, 2005 5:22 am Post subject: Re: for loop sehr langsam?? |
|
|
Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> schrieb:
| Quote: | float tmp = 0.;
for (int i = 0; i < 2000; i++) {
for (int j = i; j < 2000; j++) {
for (int k = 0; k < 9000; k++) {
tmp += tmp_mat(k,i) * tmp_mat(k,j);
}
data2d[i][j] = tmp; // Das Problem
Lass mich raten:
Dein erster Code-Abschnitt rechnet still und heimlich vor sich hin,
waehrend im zweite Code-Abschnitt die Festplatte wie verrueckt vor
sich hinroedelt?
|
Könnte sein, allerdings hat er es nur mit ca.
(2000*2000+2000*9000)*sizeof(float) zu tun, was normalerweise auf
knapp 86 MB kommen dürfte. Das ist heutzutage nicht mehr so viel,
daß gleich gepaget wird.
Ich tippe auch eher darauf, daß der Compiler da mächtig was weg-
optimiert. Aber, darf der das? Es könnte doch sein, daß in tmp_mat()
irgendwas passiert, was tatsächlich _nicht_ wegoptimiert werden
sollte.
Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|