Podivné optimalizace c++ 11 – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Podivné optimalizace c++ 11 – C / C++ – Fórum – Programujte.comPodivné optimalizace c++ 11 – C / C++ – Fórum – Programujte.com

 

p3can
~ Anonymní uživatel
312 příspěvků
28. 7. 2014   #1
-
0
-

Zdravim,

cely den si lamu hlavu nadtim, proc tento kod:

#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <ctime>
#include <thread>

 void fce(float* a, float* b, float* c, int from, int to){
	for (int i = from; i < to; i++)
	{
		c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int p = 0;
	int repeat = 3;
	while (repeat-- > 0)
	{
		int n = 20 * 1000 * 1000;
		auto a = new float[n];
		auto b = new float[n];
		auto c = new float[n];
		auto d = new float[n];

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}

		clock_t begin_time = clock();

		for (int i = 0; i < n; i++)
		{
			
			c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
		}

		
		std::cout << "\nres:   " << c[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);


		begin_time = clock();
		std::thread t5(fce, a, b, d, 0, n );
		t5.join();
		std::cout << "\nres T: " << c[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);


		delete[] a;
		delete[] b;
		delete[] c;
		delete[] d;
	}
	std::cout << "\nALL DONE";
	std::cin >> p;


	return 0;
}


ma v release (se zapnutyma sse2, jinak default; visual studio 2013) ma na mem notasu (ivy bridge i7; w8.1) tento vystup:


res:   20.5757 ela:728
res T: 20.5757 ela:329
res:   20.5757 ela:708
res T: 20.5757 ela:329
res:   20.5757 ela:704
res T: 20.5757 ela:332
ALL DONE

abych to popsal tak nechapu jak je mozne za ta stejna funkce kterou volam v cyklu trva prumerne 700ms, zatimco kdyz tuto uplne stejnou funkci spustim v thredu (pouze spustim to same v thredu nic nijak neparalelizuju) tak jak je mozne ze bezi cca 2x tak rychleji?

Nahlásit jako SPAM
IP: 77.92.213.–
KIIV
~ Moderátor
+43
God of flame
28. 7. 2014   #2
-
0
-

ono to totiz nemusi byt uplne ekvivalentni... treba pri alokaci jen system bere na vedomi, ze chces tolik a tolik ramky, ale doopravdy ji zabere az kdyz se zacne pouzivat... takze doporucuju udelat poradnej test a mit pred threadem taktez uvolneni, alokaci, inicializaci ... a po nem uvolneni

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
p3can
~ Anonymní uživatel
312 příspěvků
28. 7. 2014   #3
-
0
-

upraveno vysledky porad stejny. nejaky jiny napad?   


#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <ctime>
#include <thread>

 void fce(float* a, float* b, float* c, int from, int to){
	for (int i = from; i < to; i++)
	{
		c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int p = 0;
	int repeat = 3;
	while (repeat-- > 0)
	{
		int n = 20 * 1000 * 1000;
		auto a = new float[n];
		auto b = new float[n];
		auto c = new float[n];
		

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}

		clock_t begin_time = clock();

		for (int i = 0; i < n; i++)
		{
			
			c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
		}

		
		std::cout << "\nres:   " << c[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);

		delete[] a;
		delete[] b;
	
		a = new float[n];
		b = new float[n];
		auto d = new float[n];

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}



		begin_time = clock();
		std::thread t5(fce, a, b, d, 0, n );
		t5.join();
		std::cout << "\nres T: " << d[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);


		delete[] a;
		delete[] b;
		delete[] c;
		delete[] d;
	}
	std::cout << "\nALL DONE";
	std::cin >> p;


	return 0;
}
Nahlásit jako SPAM
IP: 77.92.213.–
KIIV
~ Moderátor
+43
God of flame
28. 7. 2014   #4
-
0
-

no jeste by se dala spoustet ta sama funkce... v obou pripadech

kazdopadne ti nic nebrani porovnat vygenerovany kod v assembleru

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
z
~ Anonymní uživatel
268 příspěvků
28. 7. 2014   #5
-
0
-

Možná se na samostatné funkci víc vyřádí. Zkus ji použít v obou případech. A taky bych pro jistotu to zjišťování konečného času dal před ten výpis, ale to nebude velký rozdíl.

Nejlepší by bylo to dekompilovat a podívat se, jestli je něco jinak.

Nahlásit jako SPAM
IP: 213.211.51.–
KIIV
~ Moderátor
+43
God of flame
28. 7. 2014   #6
-
0
-

pak bych zkusil jedno pole akorat 3x vetsi, kdy  3n bude to a  3n+1 b a 3n+2 vysledek ... cache prediction by taky mohla udelat nejake drobne zpomaleni (pokud to nezvladne predikci pro vsechny tri naraz)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
p3can
~ Anonymní uživatel
312 příspěvků
28. 7. 2014   #7
-
0
-

predelal jsem to a volam tam i tu funkci

#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <ctime>
#include <thread>

void fce(float* a, float* b, float* c, int from, int to){
	for (int i = from; i < to; i++)
	{
		c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int p = 0;
	int repeat = 3;
	while (repeat-- > 0)
	{
		int n = 20 * 1000 * 1000;
		auto a = new float[n];
		auto b = new float[n];
		auto c = new float[n];
		

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}

		clock_t begin_time = clock();

		for (int i = 0; i < n; i++)
		{
			
			c[i] = (float)(log(a[i]) / sqrt(b[i]) + exp((a[i] + 1) / (b[i] - 1)));
		}

		
		std::cout << "\nres:   " << c[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);

		delete[] a;
		delete[] b;
		delete[] c;

		a = new float[n];
		b = new float[n];
		c = new float[n];

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}

		begin_time = clock();
		fce(a, b, c, 0, n);
		std::cout << "\nres:F  " << c[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);

		delete[] a;
		delete[] b;

		// VLAKNO
		a = new float[n];
		b = new float[n];
		
		auto d = new float[n];

		for (int i = 0; i < n; i++)
		{
			a[i] = i;
			b[i] = i;
		}

		begin_time = clock();
		std::thread t5(fce, a, b, d, 0, n );
		t5.join();
		std::cout << "\nres T: " << d[2] << " ela:" << float((clock() - begin_time)) / (CLOCKS_PER_SEC / 1000.0);
		
		
		delete[] a;
		delete[] b;
		delete[] c;
		delete[] d;
		
	}
	std::cout << "\nALL DONE";
	std::cin >> p;


	return 0;
}


vystup je tento


res:   20.5757 ela:680
res:F  20.5757 ela:346
res T: 20.5757 ela:367
res:   20.5757 ela:668
res:F  20.5757 ela:343
res T: 20.5757 ela:340
res:   20.5757 ela:653
res:F  20.5757 ela:336
res T: 20.5757 ela:333
ALL DONE

pokud ovsem zapoznamkuju kod od poznamky //VLAKNO tak jsou casi res a resF stejne okolo tech 340ms.

jako me jde spis o to, ze jak ma teda pak clovek vytvorit nejaky algoritmus, kdyz na takovehle "kravine" se mu jednou vykona program za 700ms a kdyz to napise ve forme funkce (coz by melo byt logicky o nejakou nanosekundu pomalejsi) tak mu to bezi 2x rychleji (jako kdyby to bylo par % ale 2x tolik). jako jak ma clovek pak neco udelat v tom c++   

Nahlásit jako SPAM
IP: 77.92.213.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 35 hostů

Podobná vlákna

Podivně fungující switch — založil spider-x

Podivné chování jazyka C++ — založil NeprijemnePrekvapeny

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý