Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ohjelma prossun rasittamiseen

Sivun loppuun

CoolC++ [25.08.2006 09:57:03]

#

Yksinkertainen PII -ohjelma tai vastaavaa, jolla rasittaa prossua tai muistia tai näyttistä!?

-Eli mikä on yksin kertainen ohjelmointi kaava tai koodi, jolla voisi raskauttaa konetta ja lopuksi se antaa ajan paljon on kulunnut tiettyyn testiin aikaa!?

T.M. [25.08.2006 11:09:25]

#

while(1){

}

Eikös tuollaisen pitäisi käyttää kaikki tehot...

rndprogy [25.08.2006 13:04:59]

#

Nääh.
for(;;); on parempi.

sooda [25.08.2006 13:17:03]

#

for(;;)malloc(1048576); <3

Blaze [25.08.2006 14:10:54]

#

No jos nyt tälle linjalle lähdetään:

for(;;) {
  fork();
}

Edit: no jottei nyt ihan peikkoiluksi mene koko viesti, niin ehdotanpa alkuperäiselle kysyjälle vaikka alkulukujen laskemista

T.M. [25.08.2006 23:00:02]

#

Mikä tossa for(;;) rakenteessa oikein viehättää? Eikö while(1) ole paljon loogisempi?

Antti Laaksonen [26.08.2006 00:15:38]

#

Tässä on koodi, joka laskee luvun 230. Minun koneellani puuhaan menee noin yhdeksän sekuntia.

#include <stdio.h>
#include <time.h>

int m = 1;

void taso(int a) {
    if (a == 30) return;
    m++;
    taso(a + 1);
    taso(a + 1);
}

void lasku(void) {
    /* tähän voi laittaa mitä tahansa laskuja */
    taso(0);
    printf("%i\n", m);
}

int main(void) {
    clock_t alku, loppu;
    alku = clock();
    lasku();
    loppu = clock();
    printf("%.3f\n", ((float)(loppu - alku) / CLOCKS_PER_SEC));
    return 0;
}

Laskettavaa asiaa voi muuttaa funktiosta lasku. Ajastus tapahtuu kutsumalla kahdesti funktiota clock ja laskemalla näiden aikojen erotuksen.

koo [26.08.2006 23:36:18]

#

Rankin tapa on se, että ohjelmoidaan sellaisia käskysarjoja (todennäköisesti assemblyllä), että ne käyttävät mahdollisimman tehokkaasti kaikkia vehkeen pipelineja (kokonaisluku-, liukuluku-, multimedia-, ja ehdollisten haarautumisten ennustelu) rinnakkain ja mahdollisimman vähän esimerkiksi muistiviittauksia tehden. Muistiviittaukset yms. kun ovat suhteellisesti hitaita ja prossu pääsee huilaamaan odotellessaan kamaa väylältä. Tällä tapaa mahdollisimman monet miljuunat transistorit saavat töitä yhtä aikaa, sähköä kuluu ja värkki kuumenee.

Yksinkertainen tyhjä luuppi rasittaa prossua kyllä, muttei niin rajusti. On sekin kyllä simppeli tapa viedä tehoja moniajojärjestelmissä muilta prosesseilta, sillä tässäkään prosessi ei tee mitään keskeyttävää, jolloin käyttiksen skeduleri päästää muita prosesseja ajoon vain silloin, kun kuormittajan aikaviipale tulee täyteen.

for (;;); -rakenne on ja while (1); -rakennetta "tehokkaampi" siinä mielessä, että forissa ei tarvi testata mitään ehtoa ja whilessa täytyy. Siis ikään kuin näin:

// for (;;);
for_alku:
goto for_alku;

// while (1);
while_alku:
if (1) goto while_alku;

On kyllä aika hyvät mahikset, että kääntäjän optimointi tekee noista ihan samaa konekieltä joka tapauksessa.

malloc- ja fork-kikat haukkaavat systeemin resursseja, mutteivat ne prossua välttämättä niin paljon kuormita. Syy on se, että nuo funktiot saattavat tehdä sisällään systeemikutsuja ja muita temppuja, joiden aikana muut prosessit pääsevät ajoon tai prosessori idlaa muistiväyläjaksoja tavaraa odotellessaan.

Tuo clock-konsti on aika taattu konsti kuluneen ajan mittaamiseen. Eri käyttiksissä voi olla tarkempiakin funktioita tähän hommaan. Pikkukommenttina heittäisin vielä, että itse käyttäisin tuossa aikalaskussa castausta doubleksi: laskenta olisi tarkempi ja doubleksi tulos tuossa funktiokutsussa kuitenkin muuttuu.

T.M. [27.08.2006 13:16:59]

#

Heh, eikö tässä ollut tarkoitus rasittaa prosessoria? :)
Ja heti oltiin optimointia tekemässä :P

Kiitos kuitenkin selvennyksestä.

koo [27.08.2006 14:20:56]

#

T.M., meinaat varmaan tuota for-while-kysymystä. Siis tuo for on "tehokkaampi" tekemään ei-paljon-mitään, kun siinä on vähemmän käskyjä. while-versiossa tehdään periaatteessa muistiviittaus, joka voi antaa prossulle lepojaksoja. Mutta tälle tasolle kun on päästy, voisi olla jo hedelmällisempää keskustella vaikka siitä, montako enkeliä mahtuu neulan päälle...

Baglair [27.08.2006 17:42:04]

#

Kyllä se kääntäjä optimoi (ainakin itselläni) molemmat koodit samanlaiseksi.

/* for looppi */
.L2:
	jmp	.L2


/* while */
.L2:
	jmp	.L2

CoolC++ [28.08.2006 09:51:40]

#

Kiitos paljon noista vinkeistä...noi auttoi paljon ja antoi lisää ideoita. No miten tuo ajan lisääminen voisi vielä onnistua jos kun tuo anttin ohjelmaa ajaessa laskin tuon kestävän 12sek., mut se olisi vielö hyvä lisä jos se tulostaisi vielä tuon kuluneen ajan. :D

CoolC++ [28.08.2006 15:03:17]

#

Itse tuo 12sek tuli siitä kun katsoin kellosta, mutta kun huomasin lisätä tuohon vielä tuon: system("pause"); niin sain tälläiset tulokset:

1073741824
13.360

-Eli mitä nää tulokset nyt onkaan!?

niin ja tässä on C++ -versio, kommentoikaa jos siinä on jotakin väärin:

#include <stdio.h>
#include <time.h>
#include <iostream.h>

int m = 1;

void level(int a)

{
    if (a == 30) return;
    m++;
    level(a + 1);
    level(a + 1);
}

void lasku(void)
{
    /* tähän voi laittaa mitä tahansa laskuja */
    level(0);
    cout << ("%i\n", m);
}

int main(void)

{
    clock_t alku, loppu;
    alku = clock();
    lasku();
    loppu = clock();
    cout << ("%.3f\n\n", ((float)(loppu - alku) / CLOCKS_PER_SEC));
    system ("pause");
    return 0;
}

Ja vielä yks sivullinen kysymsys: mikä on "%.3f"!? onko se sama kuin \n!?

Antti Laaksonen [28.08.2006 15:05:20]

#

Ensimmäinen rivi on luku 230, jonka ohjelma laski.

Toinen rivi on laskemiseen kulunut aika sekunteina.

"%.3f" tarkoittaa, että sen kohdalle tulee float-tyyppinen liukuluku kolmen desimaalin tarkkuudella.

"\n" tarkoittaa, että sen kohdalle tulee rivinvaihto.

viznut [28.08.2006 15:28:02]

#

for(;;) muuten tuottaa kaikissa järkevissä kääntäjissä tasan saman koodin kuin while(1). Ei ole mitään mieltä generoida koodia, joka testaa erikseen, onko ykkönen erisuuri kuin nolla, koska tulos tiedetään jo valmiiksi.

for(;;) on kuitenkin lähdekoodissa esteettisesti kauniimpi kuin while(1), koska siinä on yksi merkki vähemmän ja vähemmän mielivaltaisia vakioita :)

CoolC++ [28.08.2006 15:34:36]

#

Ok, no siis koodissa ei ole mitään vikaa...itse asiassa.

-Pystyykö tuota tekemään raskaamaksikin? Eli mitä arvoja voidaan antaa tai mitä lukua tulee muuttaa jos halutaan raskampi?

koo [28.08.2006 16:06:20]

#

CoolC++, jos meinaat tehdä juttuja C++:ksi, tässä muutama muutosehdotus tuohon koodinpätkään:

// Includet oikein:
#include <ctime>
#include <iostream>
#include <iomanip>

// ...

// Funktiomäärittely järkeväksi

void lasku()

// ...

// Tulostus

        std::cout << m << "\n";

// Pääohjelma C++:lla

int main()
{
        std::clock_t alku = std::clock();
        lasku();
        std::clock_t loppu = std::clock();
        std::cout << std::setprecision(3) << static_cast<double>(loppu - alku) / CLOCKS_PER_SEC << "\n\n";
        // system ("pause");
}

Ei, en kokeillut kääntäjällä, eli näppäilyvirheitä voi olla.

Kun haluat tehdä koodin raskaammaksi, mitä oikeastaan tarkoitat? Jos raskaus tarkoittaa sitä, että suoritus syö tehoja, siis ihan sähkövirtaa, esimerkiksi Intel-tyyppiselle raudalle siinä pitää olla melko pieni luuppi, jossa on sekaisin sekä kokonais- että liukulukulaskuja muutamilla muuttujilla ja vielä siten, että laskujen lopputuloksia käytetään if-ehdoissa. Tällaista touhua voi löytää googlettamalla hakusanoilla cpuburn tai burncpu.

Suorituskykyjuttuja voi sitten arvioida myös vaikka laskemalla suurehkolla mallilla mitä tapahtuu, kun kaksi galaksia törmää toisiinsa tai tracettamalla kaikki heijastukset sun muut veden pinnasta. Tuo kahden potenssin laskeminen ei paljon lopulta poikkea siitä, että panee yhden tai useamman luupin sisäkkäin ja kasvattaa joka kierroksella laskurin arvo vaikkapa nollasta kiljoonaan (olettaen ettei optimoiva kääntäjä äkkää tätä juonta ja optimoi koko turhaa työtä pois).

Jos taas haluaa yksinkertaisesti viedä keskusyksikköaikaa muilta suorituksissa olevilta prosesseilta, for (;;); -kikka on aika yksinkertainen.

Aikaa ja resursseja saa kulutettua niinkin, että kirjoittaa ihan vaan puppua vaikkapa 100 gigan kokoisen tiedoston. Tai luo tuhansittain rinnakkaisia prosesseja.

Jos ohjelman vain täytyy kestää esimerkiksi minuutin, sen kun pistää yhden sleep(60); -funktiokutsun. Ei kylläkään kuormita siinä mielessä, että muu toiminta järjestelmässä etenee ihan tavallisesti.

Eli taas sellainen ihan peruskysymys, että mitä oikeastaan olet tekemässä.

CoolC++ [29.08.2006 08:02:39]

#

lainaus:

Kun haluat tehdä koodin raskaammaksi, mitä oikeastaan tarkoitat?

-Tarkoitan tällä, es. vaikka jotakin matemaattista toiminpidettä, jonka lasekminen menisi pidempään?

lainaus:

Eli taas sellainen ihan peruskysymys, että mitä oikeastaan olet tekemässä.

-En mitään erikoista tai tarkoituksella...vaan ihan, jotakin kun halusin vain utella onko mahdollista tai miten yksinkertaista se on, joten tuon koodinkin perusteella tuoss on jo hyvät pohjat loppulliseen versioon...:D

Zach [29.08.2006 17:48:16]

#

Hohhoijaa...Sellanen toiminpide vois olla vaikka a:n vertaaminen vähän isompaan lukuun kuin 30. Lukualueen rajat tulee kyllä äkkiä vastaan.

Metabolix [29.08.2006 21:36:58]

#

Juu, kyllähän ohjelman saa tekemään vaikka mitä tyhmää.

#include <math.h>

int main()
{
  unsigned long i, j, d;
  for (i = 1; i; ++i) {
    for (j = 1; j; ++j) {
      d = (unsigned long) sqrt(i * (double)i + j * (double)j);
    }
  }
  return 0;
}

Tämä on taas niitä vuoden järkevimpiä kysymyksiä. Jos ohjelmalla pitää pitkään kestää, niin laita se ikuiseen silmukkaan. Aivan yhtä hyödyllistä se on kuin kakkosen potenssien laskeminen Antin menetelmällä.

CoolC++ [30.08.2006 08:34:16]

#

Mikäs se (std::) onkaan!?

Blaze [30.08.2006 09:41:44]

#

Kertoopi, että seuraava asia löytyy std-nimisestä nimiavaruudesta.

CoolC++ [30.08.2006 09:54:52]

#

Eli periaatteessa ihan turha :D

Zach [30.08.2006 14:52:10]

#

Pienissä ohjelmissa nimiavaruuksilla ei juuri ole merkitystä, mutta jos esim. eri kirjastoissa on käytössä useampia samannimisiä luokkia, funktioita tms., täytyy ne erotella nimiavaruuksilla. Std-avaruuden saat lisättyä "oletukseksi" näin:

using namespace std;

Tällöin ei tarvita std:: -viittauksia.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta