Um die "Wegoptimierung" zu unterdrücken, könntest Du versuchen, ob es was bringt, die Variable j nicht mit temporärer Sichtbarkeit innerhalb der for-Schleife anzulegen, sondern persistent in der main-Funktion zu halten und dann nicht immer zu überschreiben, sondern zu akkumulieren.
Aber dafür solltest Du, wie die anderen schon sagten, wiederum den Assembler-Code anschauen.
Aber was genau willst Du denn überhaupt testen? Du willst doch nicht die Performance arithmetischer Operationen (hier Multiplikation) von C++ und C# vergleichen, sondern ihre "generelle Ausführunggeschwindigkeit", oder? Dafür musst Du natürlich auch ganz andere Anweisungen benutzen als nur sehr viele Multiplikationen. Gerade sowas wie new und delete verbraucht relativ viel "Run-Time". Arithemtische Operationen wie +, -, / und * sind absolut nichts "Krasses". Funktionsaufrufe, komplexe Mathematik, Speicherverwaltung - sowas solltest Du testen (je nach dem, was Du denn genau testen willst).
Darüber hinaus musst Du Dir vergegenwärtigen, ob die Implementationen in den verschiedenen Sprachen überhaupt signifikant vergleichbar sind. Du kannst z.B. nicht grundsätzlich davon ausgehen, dass sowas wie Methodenüberschreibungen und Up- sowie Down-Casts, new-Operatoren (oder im Gegensatz dazu Stackallokationen), Templates (oder halt Generics) etc. in den verschiedenen Sprachen 1-zu-1 vergleichbar sind. Sind sie nämlich nicht. Oder es ist genau das, was Du testen willst. Liegt halt immer dran.