Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: gcc muistialueen ylitys

juffe [16.08.2021 18:55:52]

#

Moi.
Ihan mielenkiinnosta olen koodannut softan, joka populoi arrayn satunnaisilla luvuilla 0 - 999 väliltä, jonka koko on 1007483647.
Tämän jälkeen lasketaan montako kakkosta on arrayssa.
lopuksi katsotaan aika kauanko kone ruksutti tässä tehtävässä.
Tämän olen koodannut sekä c että c#.

C# kielellä mono ruksuttaa tuota 20sek, mutta samoin tein c kielinen sanoo että out of memory. Mitä teen väärin?

Kone on 64bit ja kai tuo gcc on myös 64bit:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRAY_SIZE 1007483647
#define MIN_RAND 0
#define MAX_RAND 999

int main(void)

{
clock_t begin = clock();
int array[ARRAY_SIZE];

int a;
srand(time(NULL));
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        a=rand()%(MAX_RAND - MIN_RAND+1)+MIN_RAND;
        array[i]=a;
    }

    printf("\n");
    printf("kakkosia:\t ");

    int laske=0;
    for (int j = 0; j < ARRAY_SIZE; j++)
    {
        if (array[j]==2)
        laske++;
    }

    printf("%d,", laske);
    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("\n");
    printf("%f", time_spent);

return 0;
}

jalski [16.08.2021 20:50:28]

#

juffe kirjoitti:

C# kielellä mono ruksuttaa tuota 20sek, mutta samoin tein c kielinen sanoo että out of memory. Mitä teen väärin?

Kannattaa kysymykseen laittaa myös tuo saamasi virheilmoitus. On muuten julmetun kokoinen taulukko ja hyvä arvaus on, että oletuksena oleva pinon koko ei tuohon riitä ja tuosta tulee saamasi virheilmoitus. Kokeilepa huviksesi varata muistia taulukkoa varten vaikka malloc() funktiolla.

Metabolix [16.08.2021 21:15:38]

#

Kuten jalski epäili, varmasti et pysty pinosta varaamaan noin isoa taulukkoa oletusasetuksilla. Linuxin komentorivillä (ainakin Bashissa) on mahdollista säätää pinon maksimikokoa ennen ohjelman käynnistystä:

ulimit -s 5000000 # sallitaan noin viiden gigan pino

Koodin puolesta ratkaisuna voit tehdä taulukosta globaalin (funktion ulkopuolelle) tai staattisen (static-sanalla), tai voit varata taulukon ajon aikana malloc-funktiolla (jolloin pitää muistaa vastaava free, ellei halua pitää taulukkoa ohjelman loppuun asti).

Lopuksi voi vielä miettiä, onko järkeä arpoa luvut taulukkoon ja vasta sitten laskea kakkoset, kun suoraan voisi ensimmäisessä silmukassa laskea niitä kakkosia (tai halutessaan kaikkia lukuja 0–999) ja säästää neljä gigaa muistia.

juffe [16.08.2021 22:48:21]

#

Kiitos tuolla mallocilla rupesi toimimaan, mutta hieman noi pointterit epäselviä.....
Joo tosiaan, eihän tässä mitään järkeä olekaan. Halusin testata jonkinnäköistä suorituskykyä C ja C# välillä linux koneessa.
Jos jollain windows ja haluaa testata, niin alla koodit.
Mun lukemat oli C kielellä 14.75sek ja C# 21.5sek.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRAY_SIZE 1007483647
#define MIN_RAND 0
#define MAX_RAND 999

int main(void)

{
clock_t begin = clock();
//int array[ARRAY_SIZE];
int *array = (int*)malloc(ARRAY_SIZE * sizeof(int));

int a;
srand(time(NULL));
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        a=rand()%(MAX_RAND - MIN_RAND+1)+MIN_RAND;
        array[i]=a;
    }

    printf("\n");
    printf("kakkosia:\t ");

    int laske=0;
    for (int j = 0; j < ARRAY_SIZE; j++)
    {
        if (array[j]==2)
        laske++;
    }

    printf("%d,", laske);
    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("\n");
    printf("%f", time_spent);

return 0;
}
using System;
using System.Diagnostics;

namespace ArrayReader
{
    internal static class Program
    {
        private const int SampleCount = 1007483647;

        public static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            Random rnd = new Random();
            int[] samples = new int[SampleCount];

            sw.Start();

            for (int i = 0; i < SampleCount; i++)
            {
                samples[i] = rnd.Next(0, 999);
            }

            int count = 0;
            for (int i = 0; i < SampleCount; i++)
            {
                if (samples[i] == 2)
                    count++;
            }

            sw.Stop();

            Console.WriteLine(count);

            Console.WriteLine((float)sw.ElapsedMilliseconds/1000);

            Console.ReadKey();
        }
    }
}

Vastaus

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

Tietoa sivustosta