Registrace nového uživatele     Návod     Kluby     Archív  Lopuchu     Lopuch.cz  

Diskuze na Lopuchu,
pohlazení na duchu

Lopuch.cz

Jméno:
Heslo:
Podpora LCD:
 
Klub C, C++ [ŽP: neomezená] (kategorie Programování) moderuje Šéf Lopuchu.
Archiv

Články

Jak bezpečně ukončit vlákno z DllMain
FastAllocPool - urychlení častých alokací a dealokací
Akce a zpráva jako objekt
Tuply v C++
Efektivní alokátor malých objektů a tady druhý a třetí díl
Šablony: Být vládce kvalifikátorů
Vracíme z funkce objekty
Základy komunikace mezi procesy (ve Windows)
Multiple Interface a Instance Factory
Multithreading v C++ (ve Win32)
  Nastavení klubu     Nastavení práv     Homepage     Anketa     Přítomní     Oblíbené     Lopuch     Kategorie  
autor: 
text: 
vyplnit a 
Help
 Titulek, text příspěvku  
Opište pozpátku následující text bez prostředního znaku: dfebmsl
[ 380 ] <Novější  <<<Nejnovější  Nejstarší>>>  Starší>  
bredy 1.3.2010 12:47  806
SekoryJak jsem říkal, násobení může stát víc času, než dereference adresy. Protože dva vektory v sobě není nic jiného než jednorozměrné pole ukazatelů na jednorozměrné pole. Takže vyzvednout prvek z pozice 100,150 znamená vyzvednout stý ukazatel (adresa 100 * 4) a k němu přičíst 4 * 150 (násobění 4x je posun, narozdíl od plnohodnotného násobení)
sekory Sekory The journey of thousand miles - starts with a single step. 1.3.2010 12:24  805
Zajímavý, tak když to samé zkompiluju jako release, tak je výsledek 24ms a 22ms ve prospěch přístupu přes vektory.
sekory Sekory The journey of thousand miles - starts with a single step. 1.3.2010 11:41  804
Bredy: Máš pravdu, zkoušel jsem to jen přes Debug, nenapadlo mě, že by to mohl být nějaký větší rozdíl, schválně to zkusím. Naučit bych se to mohl... takhle používám C++ více méně jako C (kde moje znalosti taky nejsou nejvýšší), takže objektové principy a podobné věci jdou mimo mě. :)

Davpe: Díky za odkaz, to už jsem taky někde četl, ale moc následků to na mě nezanechalo, když mi to v praxi nedojde.
bredy 1.3.2010 11:26  803
SekoryNetuším proč by to mělo být pomalejší. Možná si to jen překládal v Debug konfiguraci, protože tam dává STLko spoustu kontrol, jako kontroly rozsahů. U Release by ty kontroly měly odpadnout. Přístup do pole přes vektor je pak otázka dereferencí dvou adres, u prvního způsobu je zase zdržovákem to násobení. No možná tam může hrát roli výpadek stránky z cache, která u prvního způsobu vypadne v průměru méněčasto, než u druhého. Ale tak drastický by to být nemělo.

Doporučuju se každopádně naučit C++ pořádně, než se pouštět do programování čehokoliv. C++ není PHP.

Co se zásobníku týče, pokud vytvoříš proměnnou uvnitř funkce, vznikne na zásobníku. Vždycky. Ten je omezený. Vždycky. Pokud proměnnou vytvořiš dynamicky, ať už pomocí new, nebo malloc (vektor to taky alokuje newem), tak se vytvoří v separátním prostoru, zvaném halda. Halda je omezena jen dostupnou volnou pamětí (což bývá v době swapování paměti na disk víc než instalovaná pamět).

Davpe: Ano, ale na vyšší úrovni pokud možno nealokujeme. Necháváme to do těl tříd. Používáme kontejnery, a pokud už musíme něco alokovat, tak v konstruktoru a dealokovat v destruktoru. Jinde to nemá smysl (protože výjimky). A to já třeba používám alokátory, které si hlídaji alokovanou paměť a sami se postarají o její likvidaci při zániku platnosti... a to vedle chytrých ukazatelů... které dělají totéž.
davpe Davpe 1.3.2010 08:56  802
Sekory:
První ti jde bez problému, protože se paměť alokuje na halde (při používání new nebo malloc).
Ve druhém příkladě je velikost známá při překladu (jasně, v prvním příkladě sice taky, ale kdybys tam dal proměnou, která by ti velikost načítala ze vstupu, tak ti první příklad přesto pojede, protože se paměť alokuje dynamicky, kdežto druhý se nepřeloží) a tak se pole alokuje přes zásobník. Zde je to popsané (sice to je C#, ale neva)


Bredy: K té poslední větě, vždyť new musíš taky dealokovat pomocí delete ne?
sekory Sekory The journey of thousand miles - starts with a single step. 1.3.2010 02:03  801
Bredy: Moc díky tak podrobnej popis jsem nečekal. Ten přetékající zásobník nechápu... Nechápu proč statická proměnná v něm musí být celá a dynamická ne viz toto:

int *pole=new int[1000000]; //jde bezproblému
vs.
int pole[1000000]; //nahlásí chybu

přičemž s tím dále pracuji stejně. Netušil jsem, že to jde takhle jednoduše obejít. Takže asi budu používat toto, tvůj typedef sice vypadá líp, ale používal bych něco, co nevím jak funguje (std::vector a vůbec takové použití typedef je pro mě neznámá) navíc se zdá pomalejší, v mém mini testu vychází 34ms oproti 154ms:

int *pole=new int[1000000];
    srand(timeGetTime());
    unsigned long cas=timeGetTime();
       for (int i=0;i< 1000;i++) {
          for (int j=0;j< 1000;j++)
             pole[i*1000+j]=rand();
       }

       cout<<"Cas: "<< timeGetTime()-cas<< endl;
       delete []pole;

    typedef std::vector< int> RadkaPole;
    typedef std::vector< RadkaPole> CelePole;
    CelePole pol(1000,RadkaPole(1000,0));

    cas=timeGetTime();
       for (int i=0;i< 1000;i++) {
          for (int j=0;j< 1000;j++)
             pol[i][j]=rand();
       }
       cout<<"Cas: "<< timeGetTime()-cas<< endl;



No nic musím říct, že mi to takhle po nocích už moc nemyslí jdu raději spát.
bredy 1.3.2010 00:44  800
SekoryOno to v tej chybě je popsané. Stack overflow znamená, že přetekl zásobník. Zásobník je běžně u procesu nastavený na 1MB. Takže není divu, že to přeteče.

Ono totiž takhle velké "objekty" nelze dávat do zásobníku. Je nutné to alokovat. Nevím, jestli trváš na C++ nebo jen na C. V případě C++ je to jednoduché

#include <vector>

int main(int argc, char *argv[]) 
{
  typedef std::vector<int> RadkaPole;
  typedef std::vector<RadkaPole> CelePole;
  CelePole pole(1000,RadkaPole(1000,0));
  //... a tady se jede dál

}

Zápis nahoře nejprve definuje RadkaPole jako obecný vektor hodnot typu int. Druhý řádek definuje CelePole jako obecný vektor řádek (RadkaPole). Třetí řádek pak vytváří proměnnou pole a to tak, že ji inicializuje na 1000 prvků, z nichž každý prvek (což je RadkaPole) inicializuje jako 1000x hodnota 0.

Pokud bys chtěl jen čistě C, tak tam je to náročnější. Záleží na tom, jak chceš 2D pole implementovat. První varianta je ta, že je to prostě vyhrazený kus paměti, kde se prvky skládají "zleva doprava, zezhora dolu"

Pak musíš alokovat:

int *pole = (int *)malloc(sizeof(int)*1000*1000);

do pole přistupuješ přes přepočet
pole[r * 1000 + c] //kde r je řádek, c je sloupec


Jiná varianta je nadefinovat si prvek ve tvaru jednoho řádku, jako u vektoru
typedef int JedenRadek[1000];
JedenRadek *pole = (JedenRadek *)malloc(sizeof(JedenRadek)*1000);


vlastně jsi založil pole o 1000 prvků, kdy každý prvek má 1000 intů.

Další možnost je vytvoři pole o 1000 ukazatelů na jednorozměrné pole, kde budeš alokovat 1000x pole o 1000 prvků

typedef int *JedenRadek;
typedef JedenRadek *CelePole;
CelePole pole = (CelePole)malloc(sizeof(JedenRadek)*1000);
for (int i = 0; i < 1000; i++)
   pole[i] = (JedenRadek)malloc(sizeof(int) * 1000);


Nevýhodou řešení v C je nutnost každou alokaci po skončení práce dealokovat (každý malloc musí mít svůj free). V C++ tohle odpadá.
sekory Sekory The journey of thousand miles - starts with a single step. 28.2.2010 23:51  799
Můj problém je následující, chci vytvořit poměrně velké dvourozměrné pole, ale již při následujícím kódu mi to hlásí chybu:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
int pole[1000][1000];
return 0;
}

First-chance exception at 0x00081637 in test11.exe: 0xC00000FD: Stack overflow.
Unhandled exception at 0x00081637 in test11.exe: 0xC00000FD: Stack overflow.
The program '[2928] test11.exe: Native' has exited with code -1073741571 (0xc00000fd).


Používám Visual Studio 2010. Co mám dělat, chci-li vytvořit takhle velké pole? 1000*1000*4B jsou 4MB to mi nepříjde zase tolik. Zkoušel jsem měnit nastavení Linkeru, kde jsou položky jako "Stack Reserve Size", nicméně beze změny. Předpokládám tedy, jelikož tomuhle pranic nerozumím, že sem asi trochu vedle.
huh huh 28.8.2009 18:06  797
Kdokoliv [796]: Já ti to neberu. Já bych si kvůli tomu na krk další knihovnu nevázal. To člověk může udělat vždycky. Člověk za půl roku zjistí, že chce program zkompilovat na nějaké obskurnější platformě a tejden stráví tím, že se tam snaží rozchodit cizí knihovny, na kterejch je závislej.

Příprava předem u mě spočívá v tom, že si mezi svůj kód a cizí knihovny vložím vlastní vrstvu.
kdokoliv Kdokoliv Nevidím důvod dělat cokoliv bezdůvodně. - http://kkl2401.wz.cz 28.8.2009 17:45  796
huh [795]: Hele jak bych to rekl. Ja uz tolikrat "chtel napr. to a to" a za pul roku zjistil, ze vlastne taky jeste chci (nebo nekdo jinej chce) tamhleto a tamhleto, ze uz s tim radsi pocitam predem. :-)
huh huh 28.8.2009 17:43  795
Kdokoliv [794]: No to právě záleží na tom, co chci. Pokud chci např. generovat HTML s width a height, tak opravdu nepotřebuju nic jinýho. V odkazu, co jsem linkoval je jasně uvedeno jméno souboru v distribuci IJG (tj. libjpeg), ze kterýho se to dá snadno vytáhnout.
Ono je někdy jednodušší nemít spousty závislostí, nemluvě o tom, že pokud je linkuju staticky, tak to znamená rekompilovat po každé bezpečnostní opravě.
kdokoliv Kdokoliv Nevidím důvod dělat cokoliv bezdůvodně. - http://kkl2401.wz.cz 28.8.2009 16:31  794
huh [793]: Nerikam, ze to neni zbytecny. Je teda fakt, ze jsem venoval asi tri minuty nalezeni jakehokoliv zdrojaku na tech strankach, cos linkoval, pripadne na nejblizsich referencich, a nic takovyho jsem nevidel, lec to pochopitelne nemusi znamenat nic jinyho, nez ze jsem slepej.
Ja jenom rikal, ze ja osobne bych proste sahnul po nejaky hotovy knihovne, uz jenom proto, ze implicitne predpokladam, ze budu potrebovat i neco vic nez jenom zjistit rozmery (a to i za predpokladu, ze si treba zatim ani neuvedomuju, ze to v budoucnu budu potrebovat ;-)).
huh huh 28.8.2009 14:37  793
Kdokoliv [786]: to je právě zbytečný, protože součást IJG je i krátký zdroják, jak snadno zjistit výšku a šířku, bez linkování celé jejich knihovny. Viz mnou uvedený odkaz.
kdokoliv Kdokoliv Nevidím důvod dělat cokoliv bezdůvodně. - http://kkl2401.wz.cz 28.8.2009 10:25  792
David11 [789]: Ja si teda myslim, ze otazky k nejakymu specifickymu jazyku (v tomto pripade C++) je vhodny hazet do prislusnyho klubu (tedy v tomto pripade sem). Teprve pokud tu nebude odpoved, je mozne to zobecnit a zeptat se treba v tom Programovani.
Ja myslim, ze hlavne slo o to, ze Bredyho (a nejenom jeho, me vicemene taky) asi ponekud zmatlo, ze bys nevedel o existenci libjpeg. Kazdopadne zacal bych proste treba tim.
david11 David11 - Bilbo..and the mouse police never sleeps 28.8.2009 10:17  791
BredyNo, prave ze ja tomu nejlip porozumim kdyz to je napsany v C++ : - )
Ale mas pravdu, nekdy cloveku nic jinyho nezbyde, nez porozumet kodu v jinem jazyce nez v jakem bezne pracuje. Ja obcas prepisuju kousky kodu z Fortranu do C++ a vetsinou to pochopim, ale uz se mi taky stalo, ze jsem se musel dotcneho fortranovce zeptat, co ta prapodivna konstrukce ma jako znamenat.

[ 380 ] <Novější  <<<Nejnovější  Nejstarší>>>  Starší>  

(c) 2001-2011 Lopuch.cz   
Kontakt