Napisz ktoś program potrzebuję go pomocy !!

0

Witam potrzebuję pomocy przeniosłem się z innej szkoły W której nie miałem informatyki tylko Technologie informacyjną a tu gdzie teraz jestem operują w c++ i muszę zaliczyć cały rok Pani kazała napisać program ale jak wspominałem nie ogarniam c++ i czy ktoś by był w stanie mi go napisać ?

O to polecenie

Napisz program wczytujący 10 licz całkowitych program powinien wypisać na ekranie monitora wczytane liczby oraz :
a) ich sumę
b) ilość podanych liczb podzielnych przez 3 lub 5
c) średnią arytmetyczną wczytanych licz dodatnich
I to powinno być robione w programie dev ++

7

Wyjść z Twojego problemu jest conajmniej kilka:

  1. Naucz się podstaw C++ i napisz te programy sam.
  2. Znajdź gotowca w sieci.
  3. Na luzie zalicz w przyszłym roku.
  4. Umieść ten post w dziale praca.
3

Witam potrzebuję pomocy przeniosłem się z innej szkoły

Plus za w miarę oryginalną wymówkę

W której nie miałem informatyki tylko Technologie informacyjną a tu gdzie teraz jestem operują w c++ i muszę zaliczyć cały rok

Nie znam się specjalnie na terminach, ale czy to nie jest aby to samo?

czy ktoś by był w stanie mi go napisać ?

Tia...


Moja kolej: ``` Witam! Potrzebuję pomocy; przeniosłem się z innej szkoły w której nie miałem nauki włączania odkurzacza, a tu gdzie jestem każą mi odkurzyć cały dywan, aby zaliczyć rok. Pani kazała odkurzyć mi dywan, ale jak wspomniałem nie ogarniam tego. Czy ktoś jest to w stanie zrobić za mnie? ``` * wszelkie podobieństwa niezamierzone ofc ;) *
8
Krisu332 napisał(a):

Witam potrzebuję pomocy przeniosłem się z innej szkoły W której nie miałem informatyki tylko Technologie informacyjną

W czerwcu się przeniosłeś?

2

5 dyszek i zaliczasz rok.

1

Mam dobry dzien to masz. Od razu mowie ze nie bede tlumaczyl. Wysil sie chociaz tyle i sam postaraj sie zrozumiec kod.

#include <iostream>

#define size 10

int sum(int *tab)
{
    int result = 0;
    for(int i=0;i<size;i++)
    {
        result += *(tab+i);
    }
    return result;
}

int mod3_5(int *tab)
{
    int result = 0;
    for(int i=0;i<size;i++)
    {
        (*(tab+i))%3 ? result : result++;
        (*(tab+i))%5 ? result : result++;
    }
    return result;
}

int avg(int *tab)
{
    int result = 0;
    int count = 0;
    for(int i=0;i<size;i++)
    {
        (*(tab+i))>0 ? result += *(tab+i) : result;
        (*(tab+i))>0 ? count++ : count;
    }
    count == 0 ? count++ : count;
    return result/count;
}

int main()
{
    int tab[size] = {0};
    for(int i=0;i<size;i++)
        std::cin >> *(tab+i);
    std::cout << "Suma: " <<sum(tab) << std::endl;
    std::cout << "Mod 3||5: " << mod3_5(tab) << std::endl;
    std::cout << "Srednia: " << avg(tab);
    return 0;
}
1
#include <iostream>
#include <conio.h>

using namespace std;

int wpisaneLiczby[10];

int main() {
	unsigned int suma = 0;
	unsigned int podzielne = 0;
	float srednia=0;
	
	cout << "Podaj 10 liczb: " << endl;
	
	for (int i=0; i<10; i++)
		cin >> wpisaneLiczby[i];
	
	for (int i=0; i<10; i++)
		suma += wpisaneLiczby[i];
		
	for (int i=0; i<10; i++)
		if (wpisaneLiczby[i]%3 == 0 || wpisaneLiczby[i]%5 == 0)
			podzielne++;
			
	srednia = suma/10;
	
	cout << "Suma: " << suma <<"\n";
	cout << "Podzielne przez 3 lub 5: " << podzielne << "\n";
	cout << "Srednia: " << srednia << endl;
	
	getch();
}
0

Jak to mawia mój nauczyciel programowania "ile głów tyle rozwiązań" więc zaprezentuję też swoje:

Uwaga: Robiłem w ramach rozrywki przed jutrzejszym konkursem :=)

 #include <iostream>
using namespace std;

int main()
{
	
	int liczby[5]; //deklaracja tablicy 5 elementów
	int liczba;
	int suma = 0;
	int ile = 0;
	double wart = 0;
	double suma2 = 0;

	for(int i = 0; i < 4; i++)
	{
		cout << "Podaj liczbe: ";
		cin >> liczba;
		liczby[i] = liczba;
		suma+=liczba; // suma = suma + liczba;
		ile++; // ile = ile + 1; potrzebne do średniej
	} // powyższa pętla odpowiada za podawanie liczb, zapisywanie ich do tablicy oraz liczenie ich sumy.
	cout << "Twoje liczby to: " << endl;
	for(int k = 0; k < 4; k++)
	{
		cout << liczby[k] << " ";
	} // ta pętla wyświetla podane liczby
	cout << endl;
	cout << "Suma tych liczb to: " << suma << endl;
	
	for(int j = 0; j<4; j++)
	{
		wart = liczby[j];
		suma2+=wart;
		
	} //potrzebne do średniej

	double wynik = suma2/ile;
	cout << "Srednia tych liczb to: " << wynik << endl;

	cout << endl;
	cout << "Podzielne przez 3: " << endl;
	for(int z = 0; z < 4; z++)
	{
		if(liczby[z]%3==0)
			cout << liczby[z];
	} //jeżeli liczba z tablicy jest podzielna przez 3 np. 9 to wyswietli ja jak nie to nic nie robi
		cout << endl;
	cout << "Podzielne przez 5: " << endl;
	for(int x = 0; x < 4; x++)
	{
		if(liczby[x]%5==0)
			cout << liczby[x];
	} //to samo co wyżej tylko przez 5.

	

	cin.ignore();
	cin.get();
}

A Twoja nauczycielka powiedziała pewnie "w kompilatorze devC++" to nie jest kompilator a IDE. Ja pisałem w Visualu ale powinno działać ;)
Jak nie to cin.ignore() i cin.get() zmien na system("pause"); (WIEM, że tak się nie powinno robić) i powinno to Twoją nauczycielkę zadowolić.
No i te 5 zmień sobie wszędzie na 10 skoro tyle potrzebujesz. Ja dla wygody dałem 5 bo nie chciało mi się za każdym razem 10 liczb wpisywać, żeby przetestować.

5

Skoro tak łaskawie podajecie mu kolejne rozwiązania, to może któryś z was jutro przyjdzie do mnie do domu i mi go posprząta lub przynajmniej wytrzepie rzeczony w poście #852389 dywan?
Bo ja nie umiem, bo mi się nie chce...

11

Jako ze rev narzeka ze nie korzystam z gotowych funkcji to prosze. Oddaj pani ten na pewno sie spodoba.

#include <iostream>

#define size 10

int sum(int *tab)
{
    int result = 0;
    __asm
    {
        mov ecx, size
        mov esi, tab
        Petla:
        lodsd
        add result, eax
        loop Petla
    }
    return result;
}

int mod3_5(int *tab)
{
    int result = 0;
    __asm
    {
        mov ecx, size
        mov esi, tab
        Petla:
        lodsd
        xor edx, edx
        mov ecx, eax
        mov ebx, 3
        idiv ebx
        cmp edx, 0
        jz Zwieksz
        xor edx, edx
        mov eax, ecx
        mov ebx, 5
        idiv ebx
        cmp edx, 0
        jz Zwieksz
        jmp Dalej
        Zwieksz:
        inc result
        Dalej:
        loop Petla
    }
    return result;
}

int avg(int *tab)
{
    int result = 0;
    int count = 0;
    __asm
    {
        mov ecx, size
        mov esi, tab
        Petla:
        lodsd
        cmp eax, 0
        jg Licz
        jmp Next
        Licz:
        add result, eax
        inc count
        Next:
        loop Petla
        test eax, 0
        je Zero
        jmp NieZero
        Zero:
        inc count
        NieZero:
    }
    return result/count;
}

int main()
{
    int tab[size] = {1};
    for(int i=0;i<size;i++)
        std::cin >> *(tab+i);
    std::cout << "Suma: " <<sum(tab) << std::endl;
    std::cout << "Mod 3||5: " << mod3_5(tab) << std::endl;
    std::cout << "Srednia: " << avg(tab);
    return 0;
}

Dawno nie uzywalem asma wiec to tak dla przypomnienia.

Ps. Jest maly bug ale nie zdradze jaki ;)

2
int sum(int* numbers, int count)
{
    __asm
    {
        mov    esi, numbers
        mov    ecx, count

        mov    edx, ecx
        and    edx, 1
        shr    ecx, 1

adding:
        paddd  mm0, [esi]
        add    esi, 8

        loop   adding

        movd   eax, mm0
        punpckhdq mm0, mm0
        movd   ebx, mm0
        add    eax, ebx

        emms

        cmp    edx, 0
        je     end

        add    eax, [esi]
end:
    }
}

Działa dla tablic, których liczba elementów przekracza 1. Dla parzystej ilość elementów wykonuje count/2 + 1 dodawań i jedno więcej dla nieparzystych.

Zapraszam do zabawy ;P.

0

Dzięki wskazówkom @Wibowita powstała nowa wersja:

unsigned int sum(int* numbers, int count)
{
   __asm
   {
      mov      esi, numbers
      mov      ecx, count
      shr      ecx, 4

      mov      eax, 0
adding:
      prefetchnta  [esi + 640]

      paddd   mm0, [esi     ]
      paddd   mm1, [esi + 8 ]
      paddd   mm2, [esi + 16]
      paddd   mm3, [esi + 24]
      paddd   mm4, [esi + 32]
      paddd   mm5, [esi + 40]
      paddd   mm6, [esi + 48]
      paddd   mm7, [esi + 56]
      add      esi, 64

      loop adding

      movd ebx, mm0
      add eax, ebx
      punpckhdq mm0, mm0
      movd ebx, mm0
      add eax, ebx

      movd ebx, mm1
      add eax, ebx
      punpckhdq mm1, mm1
      movd ebx, mm1
      add eax, ebx

      movd ebx, mm2
      add eax, ebx
      punpckhdq mm2, mm2
      movd ebx, mm2
      add eax, ebx

      movd ebx, mm3
      add eax, ebx
      punpckhdq mm3, mm3
      movd ebx, mm3
      add eax, ebx

      movd ebx, mm4
      add eax, ebx
      punpckhdq mm4, mm4
      movd ebx, mm4
      add eax, ebx

      movd ebx, mm5
      add eax, ebx
      punpckhdq mm5, mm5
      movd ebx, mm5
      add eax, ebx

      movd ebx, mm6
      add eax, ebx
      punpckhdq mm6, mm6
      movd ebx, mm6
      add eax, ebx

      movd ebx, mm7
      add eax, ebx
      punpckhdq mm7, mm7
      movd ebx, mm7
      add eax, ebx

      emms
   }
}

Działa tylko dla ilości elementów podzielnej przez 16.

Dla 102400000 liczb (tak, 390 megabajtów liczb) moja wersja wykonuje się w 28 milisekund, wersja z biblioteki standardowej C++ w 48, a pętla z sumowaniem w 32.

Uroczyście ogłaszam, że nie ma sensu się w to bawić i wystarczyło napisać: cout << accumulate(numbers, numbers + count, 0);.

edit: dodając prefetch udało się zejść do 26.

0
// UWAGA: numbers musi wskazywac na obszar, ktory ma 16 bajtowy alignment.
int sse2_add(int *numbers, size_t count) {
  // Rejestry, w ktorych beda posrednie sumy.
  __m128i s0 = _mm_setzero_si128();
  __m128i s1 = _mm_setzero_si128();
  __m128i s2 = _mm_setzero_si128();
  __m128i s3 = _mm_setzero_si128();
  
  // Petla dodawan.
  for (size_t i = 0; i < count; i += 16) {   
    _mm_prefetch(reinterpret_cast<char *>(numbers + i + 1024), _MM_HINT_NTA);
    
    s0 = _mm_add_epi32(s0, *reinterpret_cast<__m128i *>(numbers + i));
    s1 = _mm_add_epi32(s1, *reinterpret_cast<__m128i *>(numbers + i + 4));
    s2 = _mm_add_epi32(s2, *reinterpret_cast<__m128i *>(numbers + i + 8));
    s3 = _mm_add_epi32(s3, *reinterpret_cast<__m128i *>(numbers + i + 12));  
  }

  // Dodanie tych 4 rejestrow.
  s0 = _mm_add_epi32(_mm_add_epi32(s0, s1), _mm_add_epi32(s2, s3));
  
  // Poziome dodanie 1 rejestru.
  s0 = _mm_add_epi32(s0, _mm_srli_si128(s0, 8));
  s0 = _mm_add_epi32(s0, _mm_srli_si128(s0, 4));

  // Wynik.
  return _mm_cvtsi128_si32(s0);
}

Wynik dla 1000 powtórzeń: 56.467ms na iterację. (6.7 GiB/s)
Wynik dla kodu @Rev: 56.561ms na iterację.
I tak to pływa w zależności od liczby w prefetchu.

(Phenom II 3.2 GHz, DDR2 PC-6400, VS2010)

Wnioski: AMD jest jednak do d**y to chyba jednak RAM ogranicza, GCC + inline asm = fail.

Jak ktoś będzie chciał sprawdzić u siebie, to potrzeba #include <emmintrin.h> i włączonej obsługi SSE2. Co do alignmentu, to na Windowsie jest _aligned_malloc(size, align) z <malloc.h> oraz _aligned_free(pointer) a na Linuksie posix_memalign(&pointer, align, size) z <cstdlib> oraz zwykłe free.

Edit: zauważyłem, że zmiana adresu w prefetchu poważnie wpływa na wynik. Poważnie tzn. +- 2ms. Z drugiej strony nie jest to niebezpieczne wpisywać tam sobie tak cokolwiek?

0

Zanim zaczniecie optymalizować zobaczcie ile u was zajmuje prosty strlen. Być może wąskim gardłem jest pamięć RAM, a nie jednostki obliczeniowe.

ATSD:
Agner Fog opakował intrinsics w klasy C++ - plik vectorclass.zip na http://agner.org/optimize/

0

Widzę że aby uzyskać rozwiązanie jakiegoś zadania, najlepiej urządzić konkurs ;)

0

Post @Krisu332 (dla niewtajemniczonych: autora wątku) ma chyba najwięcej minusów w historii :D

0

A może tak autor wątku się odezwie? Powie, które rozwiązanie wybrał i podziękuje?

0

Użyłem libki vectorclass.zip od Agnera Foga i napisałem takowy kod:

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <numeric>
#include <stdint.h>

#include "vectorclass.h"

int32_t x86_add(int32_t const * const numbers, size_t const count) {
    return std::accumulate(numbers, numbers + count, 0);
}

int32_t sse2_add(int32_t const * const numbers, size_t const count) {
    Vec4i a(0);
    Vec4i b(0);
    Vec4i c(0);
    Vec4i d(0);
    for (int32_t i = 0; i < count; i += 16) {
        a += Vec4i().load(numbers + i + 0);
        b += Vec4i().load(numbers + i + 4);
        c += Vec4i().load(numbers + i + 8);
        d += Vec4i().load(numbers + i + 12);
    }
    return horizontal_add(a + b + c + d);
}

int main() {
    int32_t const size = 102400000;
    int32_t const iterations = 100;
    int32_t * const numbers = new int32_t[size];
    for (int32_t i = 0; i < size; i++)
        numbers[i] = rand();
    int32_t const savedFirstNumber = numbers[0];
    clock_t startTime;
    int32_t sum;
    std::cout << "intrinsics add" << std::endl;
    numbers[0] = savedFirstNumber;
    startTime = clock();
    sum = 0;
    for (int32_t i = 0; i < iterations; i++) {
        sum += sse2_add(numbers, size);
        numbers[0] += numbers[std::max(0, sum % size)];
    }
    std::cout << "time per iteration: " << (((double) (clock() - startTime)) /
            (CLOCKS_PER_SEC * iterations)) * 1000 << " ms" << std::endl;
    std::cout << "sum: " << sum << std::endl;
    std::cout << "plain loop add" << std::endl;
    numbers[0] = savedFirstNumber;
    startTime = clock();
    sum = 0;
    for (int32_t i = 0; i < iterations; i++) {
        sum += x86_add(numbers, size);
        numbers[0] += numbers[std::max(0, sum % size)];
    }
    std::cout << "time per iteration: " << (((double) (clock() - startTime)) /
            (CLOCKS_PER_SEC * iterations)) * 1000 << " ms" << std::endl;
    std::cout << "sum: " << sum << std::endl;
    delete [] numbers;
    return EXIT_SUCCESS;
}

Mam Core 2 Duo E8400, dual-channel DDR2-800, Ubuntu, GCC 4.6.3, 64-bit. Kompilacja pod NetBeans, konfiguracja Performance Release (-O3 i takie tam bzdety), -march=native.

Przy dołożeniu opcji -fno-tree-vectorize dostaję takie wyniki:

intrinsics add
time per iteration: 70.8 ms
sum: -258269702
plain loop add
time per iteration: 85.3 ms
sum: -258269702

RUN SUCCESSFUL (total time: 16s)

Bez tej opcji dostaję:

intrinsics add
time per iteration: 70 ms
sum: -258269702
plain loop add
time per iteration: 66.4 ms
sum: -258269702

RUN SUCCESSFUL (total time: 14s)

Wnioski:

  • wektoryzacja super prostych pętli w GCC działa dobrze :)
  • wąskim gardłem jest dostęp do RAM,

Update:
Zrobiłem jeszcze implementację w Javie:

import java.util.Random;


public class Main {
    
    int sum(int[] numbers) {
        int sum = 0;
        for (int v : numbers) {
            sum += v;
        }
        return sum;
    }
    
    void run() {
        final int size = 102400000;
        int[] numbers = new int[size];
        Random rand = new Random();
        for (int i = 0; i < size; i++) {
            numbers[i] = rand.nextInt();
        }
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += sum(numbers);
            numbers[0] += numbers[rand.nextInt(size)];
        }
        final long time = System.currentTimeMillis();
        for (int i = 0; i < 100; i++) {
            sum += sum(numbers);
            numbers[0] += numbers[rand.nextInt(size)];
        }
        System.out.println((double) (System.currentTimeMillis() - time) / 100);
        System.out.println(sum);
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

Czas ok 75 ms na iterację.

1 użytkowników online, w tym zalogowanych: 0, gości: 1