játékfejlesztés.hu
FórumGarázsprojectekCikkekSegédletekJf.hu versenyekKapcsolatokEgyebek
Legaktívabb fórumozók:
Asylum:    5504
FZoli:    4894
Kuz:    4455
gaborlabor:    4449
kicsy:    4304
TPG:    3402
monostoria:    3284
DMG:    3172
HomeGnome:    2919
Matzi:    2528

Pretender:    2498
szeki:    2440
Seeting:    2306
Geri:    2198
Orphy:    1893
Joga:    1791
Bacce:    1783
MaNiAc:    1735
ddbwo:    1654
syam:    1491
Frissebbek | Korábbi postok
[1] > 2 < [3] [4] [5] [6] [7] [8] [9] [10] [15] [20] [25] [30] [35] [40] [45] [50] [55] [60] [65] [70] [75] [80] [85] [90] [95] [100] [105] [110] [115] [120] [125] [130] [135] [140] [143]
Instalok - Tag | 619 hsz       Online status #212338   2019.02.14 08:26 GMT+1 óra  
Idézet
Matzi :
Szerintem ha benchmarkolni akarod, akkor inkább a sima gyokre számítsd át. Ritkábban kell az inverz gyok, mint a sima, az std megoldását meg ezzel pluszban bunteted, a tobbit meg nem osztod vissza. Nem hiszem hogy nagyon sok múlna rajta, de azért úgy a korrekt.


Igen, ez igaz lehet, de meglepően sokszor kellhet az inverz gyök. Például, ha normalizálsz egy vektort, akkor érdemesebb az inverz gyököt kiszámolni, és a komponenseket végigszorozni vele, mintsem a hosszát (azaz simán gyököt) számolni, és azzal osztani.

Egyébként ez valóban egy mikro-optimalizáció csak legfeljebb, ráadásul kicsit kiszámíthatatlan, hiszen nagyban függ attól, hogy az sqrt hogyan van megvalósítva.

Sőt, nagyon úgy tűnik, hogy az sqrt-t nem érdemes sse utasításra átírni, ha csak egyetlen 32 bites floating point kiszámítása a cél.
Kód:
inline float sqrt_sse(float f)
{
    return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(f)));
}

inline float sqrt_std(float f)
{
    return ::sqrtf(f);
}

MSVC x86 release
Kód:
sse - 2.690902
std - 2.769703

Online compiler
Kód:
sse - 17.221019
std - 17.279860

   
Matzi - Szerkesztő | 2528 hsz       Online status #212337   2019.02.14 00:54 GMT+1 óra  
Szerintem ha benchmarkolni akarod, akkor inkább a sima gyokre számítsd át. Ritkábban kell az inverz gyok, mint a sima, az std megoldását meg ezzel pluszban bunteted, a tobbit meg nem osztod vissza. Nem hiszem hogy nagyon sok múlna rajta, de azért úgy a korrekt.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
   
Instalok - Tag | 619 hsz       Online status #212336   2019.02.13 11:14 GMT+1 óra  
Találtam az UE4 forráskódban, majd később egy cikkben lehetséges gyorsítást (a pontosság rovására) az inverz gyök számítására. Ennek örömére csináltam is egy kis tesztet. Ha a számok nem hazudnak, akkor az invSqrt a leggyorsabb az összes közül. Valahol érthető, az SSE inkább párhuzamos (pl. 4x32 bit) számításokra való, mintsem 32 bitnyi adatokkal dolgozni.
Kód:
#include <emmintrin.h>
#include <cmath>

inline float invSqrt(float f)
{
    const float x0 = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(f)));
    return (x0 * (1.5f - 0.5f * f * x0 * x0));
}

inline float invSqrt_SSE(float f)
{
    const __m128 v = _mm_set_ss(f);
    const __m128 oneHalf = _mm_set_ss(0.5f);
    const __m128 x0 = _mm_rsqrt_ss(v); // 1/sqrt(f) estimate
    const __m128 x1 = _mm_add_ss(
        x0,
        _mm_mul_ss(
            x0,
            _mm_sub_ss(
                oneHalf,
                _mm_mul_ss(
                    _mm_mul_ss(oneHalf, v),
                    _mm_mul_ss(x0, x0)
                )
            )
        )
    );

    return _mm_cvtss_f32(x1);
}

inline float invSqrt_std(float f)
{
    return 1.0f / std::sqrt(f);
}

#include <stdio.h>

#ifdef _MSC_VER
#include <intrin.h>
#pragma intrinsic(__rdtsc)
#else
extern __inline unsigned long long
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
__rdtsc(void)
{
    return __builtin_ia32_rdtsc();
}
#endif

int main()
{
    static constexpr int COUNT = 8 * 1000 * 1000;
    static float f_in[COUNT];
    static float f_out[COUNT];

    for (int i = 0; i < COUNT; ++i) {
        f_in[i] = (float)i;
    }

    unsigned long long t;

    // warm cache
    for (int i = 0; i < COUNT; ++i) {
        f_out[i] = f_in[i];
    }

    // sse + scalar
    t = __rdtsc();
    for (int i = 0; i < COUNT; ++i) {
        f_out[i] = invSqrt(f_in[i]);
    }
    t = __rdtsc() - t;
    printf("invSqrt     - %f\n", (double)t / COUNT);

    // full sse
    t = __rdtsc();
    for (int i = 0; i < COUNT; ++i) {
        f_out[i] = invSqrt_SSE(f_in[i]);
    }
    t = __rdtsc() - t;
    printf("invSqrt_SSE - %f\n", (double)t / COUNT);

    // scalar with std::sqrtf
    t = __rdtsc();
    for (int i = 0; i < COUNT; ++i) {
        f_out[i] = invSqrt_std(f_in[i]);
    }
    t = __rdtsc() - t;
    printf("invSqrt_std - %f\n", (double)t / COUNT);

    return 0;
}

Nálam, MSVC x64 release fordítással:
Kód:
invsqrt     - 2.973184
invSqrt_SSE - 3.576144
invSqrt_std - 3.952989

Egy online compilerrel pedig
Kód:
invsqrt     - 5.130434
invSqrt_SSE - 6.854230
invSqrt_std - 29.393122


szerk.:
Ha valakit esetleg érdekelne, akkor itt van az iterációs módszer levezetése:
Kód:
x = f^-0.5
x^2 = f^-1
x^-2 = f
F(x) = x^-2 - f
F'(x) = -2x^-3

x1 = x0 - F(x0)/F'(x0)
x1 = x0 - (x0^-2 - f) / (-2x0^-3)
x1 = x0 - (x0^-2 - f) * (-1/2)*x0^3
x1 = x0 - (x0 - f * x0^3) * (-1/2)
x1 = x0 + 0.5 * x0 * (1 - f * x0^2)
x1 = x0 + x0 * (0.5 - 0.5 * f * x0^2)

or in another form:
x1 = x0 * (1.5 - 0.5 * f * x0^2)

   
Parallax - Tag | 609 hsz       Online status #212300   2019.01.05 19:31 GMT+1 óra  
Nekem VS alatt sincs gond Android, meg egyéb fejlesztésekkel, amiket közös solution-ben lehet fordítani/futtatni. Szépen be lehet állítani melyik milyen CPU-ra forduljon, melyik compilerrel és a többi. Ezerszer egyszerűbb volt belőni hozzá a build/emulator környezetet, mint AndroidStudio-hoz. Ott a Shared project is, ahol a közös kódot fel lehet venni és mintha egy lib lenne csatolni referencia ként. Választható Unit teszt környezet, meg ilyenek.

CMake-t használom freelancer munkákhoz, mert a megbízó mániája, hogy ne kösse le magát egy IDE-hez, neki valamiért a CB tetszik. Ez addig jó, amíg ConsoleApp-ot kell fejleszteni. Ha már picit bonyolultabb QT, vagy egyéb kell, akkor már előjönnek az IF (MSVC), meg hasonlók és lehet keresgélni mihez mit kell beállítani. Egy előnyét tapasztaltam eddig (túl az IDE függetlenségen), hogy egy raw textet igényel csak a cucc és kész. Viszont például, ha egy UWP-s project is van a "solution-ben"(mert win store-re is készül, ne adj isten Xbox-ra) már speciális MS build kell ebből és mellékelni kell magát a CMake-t is a projecthez. Annyit nem ér az egész, hogy még ezzel is molyoljak.

Ezt a hozzászólást Parallax módosította (2019.01.05 19:42 GMT+1 óra, 256 nap)

   
Matzi - Szerkesztő | 2528 hsz       Online status #212251   2018.11.20 19:46 GMT+1 óra  
A legújabb visual studio már támogatja azt, hogy cmake fileból használd, nem kell hozzá projekt file elvileg. https://blogs.msdn.microsoft.com/vcblog/2016/10/05/cmake-support-in-visual-studio/
Mellesleg pont most néztem, hogy vannak toolok amik oda vissza tudnak konvertálni a ketto kozott. Mondjuk tuti vannak korlátaik, meg nem is túl praktikus sokszor csinálni.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
   
zeller - Törzstag | 489 hsz       Online status #212250   2018.11.20 19:28 GMT+1 óra  
1. nem, csak ha extrem preformance igenyek vannak, ami miatt mondjuk egy butabb, de emiatt gyorsabb/kisebb implementacio jobban megfelel
2. same as 1, de std namespace-t tuti nem szennyeznem. semmi kozom hozza, stdlib coding convention
3. llvm + cmake, es clion ide vagy emacs

   
Asylum - Törzstag | 5504 hsz       Online status #212249   2018.11.20 08:51 GMT+1 óra  
1) nem
2) csak ha nincs az STL-ben

Coding convention: a sajátodra mindig a sajátodat.

3) vs-ben először is property sheet, hogy ne kelljen minden újabb modulnál mindent beállítani. Ami vs specifikus, azt absztraktálni. XCode-ban szintén van hasonló, ott config fájlnak hívják, a hátránya hogy kézzel kell összepakolni (de azt meg lehet csinálni, hogy project/target settingsben nyomsz egy Cmd+C -t és akkor a vágólapra másolja a config fájl formátumában. Android Studiot nem ismerem annyira, de az új build rendszerükkel ugyanezek szintén megtehetők (mondjuk én még mindig az ant-ot preferálom és a makefile-okat kézzel pakolom össze [kevesebb szarakodás, debugolni meg nem akarok; elég a logcat]).

Btw. nemrég kezdtem el refaktorálni a cikkeim kódmelléjletét, és azt ezekre az irányelvekre alapoztam (de a tegnapi után elég erősen elment a kedvem)
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #212247   2018.11.20 07:44 GMT+1 óra  
Ha most kezdenétek egy új cpp projektet, az alábbi felvetésekre milyen megoldást választanátok? Nem maga a kérdés létjogosultsága az érdekes, tegyük fel, hogy szükség van rá.

1) Saját container osztályok
2) Saját algoritmusok / algoritmusok a saját containereken
- std namespace alatt? saját namespace?
- stl coding convention (push_back, stb.) követése, vagy a saját (esetleg PushBack)?
- ha saját coding convention, akkor hogy egyeztetitek össze az std namespace alatti dolgokkal? Úgy értem, hogy felhasználói oldalról csúnya lenne, hogy az egyik containeren push_back() hívások, a másikon meg Add() vagy PushBack() hívások vanak.

3) Build system
A Visual Studio elég kényelmes IDE. Jó a debuggere, lehet vele GUI szinten compilert állítgatni, lehet vele szépen projektekbe rendezni a forráskódot, stb. Viszont:
- Valahogy biztosan össze lehet hákolni más compilerrel is, de alapból MSVC van (így, ha clang-et / gcc-t / egyebet akar használni az ember, akkor bukta)
- Ha cross-platform a cél, akkor a compiler része nem lesz ideális
- Esetleg CMake? Ha CMake, akkor milyen megoldást választotok? VS-ben fejlesztés, és portolás a végén? Esetleg CMake és VS projektek folyamatos szinkronizálása?

   
Tomi0811 - Tag | 6 hsz       Online status #212211   2018.10.25 21:02 GMT+1 óra  
köszönöm a segítséget

   
Asylum - Törzstag | 5504 hsz       Online status #212205   2018.10.22 16:11 GMT+1 óra  
http://m.cdn.blog.hu/da/darthasylum/tutorials/C++/ch21_controls.html

Illetve a blogomon találhatóak egyéb példakódok is win32 programozásra.
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Tomi0811 - Tag | 6 hsz       Online status #212199   2018.10.19 17:25 GMT+1 óra  
köszönöm a segítséget. és ezeket honnan tudom megtanulni?

   
fpeti - Törzstag | 1295 hsz       Online status #212198   2018.10.19 16:19 GMT+1 óra  
CreateWindowEx() fv-el lehet win-es ablakot csinálni, rajzolni windows-osan GDI+ pl, ha szoftveres rendereléshez kéne,a kor tudom ajánlani még a DIB-et (Device Independent Bitmap). Ezt lehet lockolni, rajzolni bele, majd kirajzolni az a bitmapet az ablakba.
   
Tomi0811 - Tag | 6 hsz       Online status #212197   2018.10.19 14:24 GMT+1 óra  
Sziasztok
Hogyan lehet a legegyszerűbben lib nélkül c++ ban olyan ablakot csinálni amire lehet rajzolni ?

   
NKCREATIV - Tag | 26 hsz       Online status #211829   2018.01.27 02:46 GMT+1 óra  
Objective c / ios alkalmazásfejlesztő

Global Social Network tervezésére / kifejlesztésére keresünk szakembert.



Feladatok

AWS Cloud Platform (Amazon Web Services) folyamatos használata az alkalmazások fejlesztéséhez
Komplex problémák megoldása és kivitelezése
Proaktív részvétel és hozzáállás az újonnan beérkező feladatok kapcsán
Elvárások

Minimum 2 év objective c fejlesztői tapasztalat
Felsőfokú szakirányú végzettség vagy ezzel egyenértékű szakmai Tapasztalat
Jó kommunikációs képesség angolul és magyarul
Nyitottság az új technológiák felé
Képesség önálló munkavégzésre
Analitikus gondolkodásmód
Kreatív problémamegoldó készség
Igény a folyamatos fejlődésre
MYSQL tapasztalat
SWIFT fejlesztői környezet ismerete
Előny:

Más technológiákban szerzett tudás: Google Cloud Platform
Egyéb programozási és szoftverfejlesztői tapasztalat
Amit kínálunk

Rugalmas munkavégzés
Támogató környezet, mely elősegíti a folyamatos szakmai fejlődést és az erősségek felderítését
Együttműködő csapat
Munkavégzés helye

Budapest

bkmedia.kft@gmail.com

   
Instalok - Tag | 619 hsz       Online status #211736   2017.12.18 07:34 GMT+1 óra  
@Wolfee:
Implementációs okból nem memcpy-t hív, mert az MSVC implementációjából megnézve a kódot azonos típus esetén az is_trivially_copyable traits mellett az is_trivial traitsnek is igaznak kell lennie. Mivel a (lent megtalálható) Foo-nak van user-defined konstruktora, így az már nem is_trivial, tehát nem fog memcpy-t használni.

Itt van az MSVC implementációja. Nem vészes, ki lehet bogarászni: https://pastebin.com/6HHQ1xLd

A kérdés igazából azzal kapcsolatos lett volna, hogy vajon miért vizsgálják pluszban azt, hogy trivial type-nak kell lennie, miért nem elég, ha trivially copyable. Tehát van-e olyan eset, amire nem gondoltam, és, ha nem trivial lenne (de trivially copyable), akkor nem működhetne a memcpy.

   
Wolfee - Törzstag | 1337 hsz       Online status #211735   2017.12.18 03:02 GMT+1 óra  
@Instalok: probald meg, hogy
a) a raw nem uint8[], hanem int[], vagy Foo[], hatha a nem tipusazonossag zavarja meg
b) nem int-et tarolni a Foo-ban, hanem mondjuk int64_t-t. Gondolom x86ra forditasz, ahol egy int 32 bites, tehat nincs valodi sporolas a memcpy hivassal (viszont biztonsagosabb)
c) debug es release build ugyanazt csinalja?
FZoli jóváhagyásával XD

   
Instalok - Tag | 619 hsz       Online status #211680   2017.11.24 20:56 GMT+1 óra  
Csak nézegettem a MS implementációjában az STL-t, és még mindig nem jöttem rá, hogy miért ennyire szigorú a memcpy optimalizálással.

Alapból ugye kb. ennyi egy uninitialized_copy:
Kód:
template <typename T, typename... Args>
inline void construct_in_place(T& obj, Args&&... args)
{
    ::new (static_cast<void*>(addressof(obj)) T(forward<Args>(args)...);
}

template <typename In, typename Out>
inline Out uninitialized_copy(In first, In last, Out dest)
{
    for (; first != last; ++first, ++dest)
        construct_in_place(*dest, *first);
}

Ezt ugye bizonyos esetekben ki lehet optimalizálni egy memcpy (pontosabban memmove) hívással. Az, hogy mi ez a helyzet, túlságosan szigorú az MS szemléletében. A lenti példát tekintve pl., nem látok semmi okot arra, hogy a Foo miért ne lehetne memcpy-zható.

Tehát az MS STL implementációjában túl szigorú ez az elbírálás, és csak próbáltam egy olyan esetet keresni, amikor nekik lenne igazuk. A memcpy leírja egyébként, hogy:
Idézet
If the objects are not TriviallyCopyable, the behavior of memcpy is not specified and may be undefined

http://en.cppreference.com/w/cpp/string/byte/memcpy
De a lenti Foo például trivially copyable, mégsem optimalizálja ki az uninitialized_copy memcpy hívásra.

   
Asylum - Törzstag | 5504 hsz       Online status #211679   2017.11.24 15:03 GMT+1 óra  
A szabvány semmi optimot nem követel meg, azt mondja lineáris időben kötelező mennie.

http://en.cppreference.com/w/cpp/memory/uninitialized_copy

amúgymeg ménem elég neked a memcpy() ?
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #211677   2017.11.24 09:12 GMT+1 óra  
Találós kérdés:
Kód:
struct Foo
{
    int i;

    Foo() noexcept
        : i(10)
    {
    }

    Foo(const Foo&) = default;
};

void test()
{
    // bocsi...
    uint8 raw[256];
    Foo* dest = (Foo*)raw;
    Foo src[] = { Foo(), Foo() };

    bool b = std::is_trivially_copy_constructible<Foo>::value;  // true
    bool b2 = std::is_trivially_copyable<Foo>::value;           // true

    memcpy(dest, src, sizeof(src)); // jónak tűnik

    // nem használja a memcpy/memmove lehetőséget
    // egyesével hívja a Foo(const Foo&)-t
    std::uninitialized_copy(src, src + sizeof(src) / sizeof(src[0]), dest);
}

Miért van az, hogy az uninitialized_copy erre a típusra nem használja a memcpy optimalizációt? Az okát tudom (a user-defined konstruktor), csak a hátterét nem értem.

   
Instalok - Tag | 619 hsz       Online status #210977   2017.02.07 18:23 GMT+1 óra  
Nahát, meglepődve jöttem rá, hogy
Kód:
T1 t1;

nem (feltétlen) ugyan az, mint
Kód:
T1 t1{};

továbbá az
Kód:
int a;

nem ugyan az, mint
Kód:
int a{};

Hogy mik vannak.

Default Initialization
Value Initialization

   
Asylum - Törzstag | 5504 hsz       Online status #210938   2017.02.03 22:53 GMT+1 óra  
Nekem inkább azt szokták mondani h a röhögéstől nem tudnak kódolni (pozitív értelemben)
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #210936   2017.02.03 19:46 GMT+1 óra  
De más meg nem írt sehol deklarációt/definíciót.

Amúgy ja, a blog tényleg jó, emberi nyelven van megfogalmazva.

   
Asylum - Törzstag | 5504 hsz       Online status #210932   2017.02.03 18:37 GMT+1 óra  
@Instalok: b+ nem neked mondtam, a te hsz-ed tökéletesen helyes volt, ne legyél már ilyen érzékeny...

@Bukta: a blogomról többet tanulhatsz, mint gondolnáld Ha valamit nem értesz kérdezz.
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Bukta - Tag | 308 hsz       Online status #210928   2017.02.02 20:07 GMT+1 óra  
Ja igen kösz Instalok, ez így már oké lett

Asylum aa tényleg a blogodon is van cpp. Na ezt már elfeledtem, majd ezt is végigfutom
ArgumenException: A megadott DependencyObject nem ehhez a Freezable elemhez tartozó környezet. Paraméter neve: context
:oO Mi a???
   
Instalok - Tag | 619 hsz       Online status #210926   2017.02.02 19:04 GMT+1 óra  
Tökéletesen használtam a definíció fogalmát. Idézve a cikkedből:
Idézet
Azt amikor megmondjuk egy változó típusát és nevét, deklarációnak hívjuk (pl. extern int i. Amikor a változónak "memória foglalódik" az a definíció (pl. int i. Egy változót tetszőlegesen sokszor lehet deklarálni, de pontosan egyszer lehet csak definiálni.

Ha azt a sort leírod még egyszer, akkor multiple definition lesz. Próbáld csak ki.

@Bukta
A lényeg ennyi:
Kód:
// header

#include <vector>

struct Foo
{
    static std::vector<int> cucc;

    static void use();
};

// cpp

std::vector<int> Foo::cucc;

void Foo::use()
{
    cucc.clear();
}

Ezt a hozzászólást Instalok módosította (2017.02.02 19:13 GMT+1 óra, 958 nap)

   
Asylum - Törzstag | 5504 hsz       Online status #210925   2017.02.02 19:00 GMT+1 óra  
Bakker tényleg olyan qva nehéz megtanulni mi a különbség deklaráció és definíció között? Mi a sz*rnak írom ezt a rengeteg cikket????

http://darthasylum.blog.hu
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #210922   2017.02.02 18:45 GMT+1 óra  
Nem-nem, nem úgy.
Kód:
// cpp

// definíció
std::vector<Vector3> Foo::positions;

void doit()
{
    // használat
    positions.clear();
}

A typedef meg azért jó, h ne kelljen 50 helyen leírni a típust: std::vector<Vector3> hanem helyette Vectors.

   
Bukta - Tag | 308 hsz       Online status #210921   2017.02.02 18:24 GMT+1 óra  
Hogy őszinte legyek, nem jött össze még mindig error-t dob:
error: qualified-id in declaration before '.' token
std::vector<Vector3> ObjMeshLoader::positions.clear();


Csak most más a szöveg. Az ObjMeshLoader.cpp-be. Typedef C-ből ismerős, de anélkül is mukodni kéne szerintem (Persze majd megnézem C++-ba miként van)
ArgumenException: A megadott DependencyObject nem ehhez a Freezable elemhez tartozó környezet. Paraméter neve: context
:oO Mi a???
   
Instalok - Tag | 619 hsz       Online status #210919   2017.02.02 16:10 GMT+1 óra  
Kód:
// header

class Foo
{
static std::vector<Vector3> positions;
};

// cpp

std::vector<Vector3> Foo::positions;

+ nézz utána a typedef-nek is, elég hasznos
Kód:
typedef std::vector<Vector3> Vectors;

   
Bukta - Tag | 308 hsz       Online status #210918   2017.02.02 15:40 GMT+1 óra  
Hali
C++ tanulok, eddig C#-oztam és vannak problémák Van nekem egy objmeshloader.h amibe van egy statikus vector<Vector3>. Na most az objmeshloader.cpp-be Undefined reference 'ObjMeshLoader::positions' error-t ír ki. Nem tudok rájönni miért (am #include "objmeshloader.h" ott can a objmeshloader.cpp-be). Statikus a változó, a fv amibe használom csak a class nem statikus, de ha azzá teszem megint előjön valami más hiba...

Kód:
static std::vector<Vector3> positions;


Kód:
positions.clear();
ArgumenException: A megadott DependencyObject nem ehhez a Freezable elemhez tartozó környezet. Paraméter neve: context
:oO Mi a???
   
Instalok - Tag | 619 hsz       Online status #210796   2017.01.16 09:01 GMT+1 óra  
Azt írták itt-ott, hogy nem annyira optimális scalarokat const refként használni. Az EASTL esetében például azt írták: (bár ez ugye a return-re vonatkozik, nem a paraméterre)
Kód:
/// Some compilers (e.g. VS20003 - VS2013) generate poor code for the case of 
/// scalars returned by reference, so we provide a specialization for those cases.
/// The specialization returns T by value instead of reference, which is
/// not that the Standard specifies.

template <typename T>
inline EA_CONSTEXPR typename eastl::enable_if<eastl::is_scalar<T>::value, T>::type
min(T a, T b)
{
    return b < a ? b : a;
}

template <typename T>
inline typename eastl::enable_if<!eastl::is_scalar<T>::value, const T&>::type
min(const T& a, const T& b)
{
    return b < a ? b : a;
}

Persze egyelőre úgy hagytam const refként, mert hát miért is ne. Release buildet meg majd nem MSVC-vel fordítok, hanem GCC-vel.

   
Asylum - Törzstag | 5504 hsz       Online status #210795   2017.01.16 08:55 GMT+1 óra  
Miért baj a const ref? Semmi extra memóriát nem jelent. Ennél elegánsabb megoldás egyébként a template specializáció.

Kód:
template <typename T>
T Abs(const T& a) { ... }

template <int>
int Abs(int a) { ... }


Vagy valami hasonló, majd bent kipróbálom.
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #210794   2017.01.14 23:59 GMT+1 óra  
Elkezdtem valami ilyesmivel próbálkozni, hogy scalar típusokra ne const refet használjak.
Kód:
using SelectArgT = conditional_t<is_scalar<T>::value, const T, const T&>

template <typename T>
static T Abs(SelectArgT<T> val);

A probléma annyi, hogy azt mondja a fordító, hogy: could not deduce template argument for 'T'. Ami valahol érthető, valahol meg mégsem. Persze megoldható lenne úgy, hogy pl. Abs<uint32>(...), de ezt el szeretném kerülni.

Persze annyira pici ez a függvényt, hogy enable_if és újraimplementálás segítségével meg tudom csinálni. Azonban kíváncsi vagyok, hogy meg lehet-e oldani másképp.

   
Parallax - Tag | 609 hsz       Online status #210786   2017.01.11 07:03 GMT+1 óra  
Saját cuccokat akkor érdemes írni, ha azok több funkciót nyújtanak és/vagy gyorsabban működnek és/vagy átláthatóbbak. Mivel úgyis TDD-vel dolgozik az ember, vagy legalábbis lefedett tesztekkel a cucc a működés helyessége itt is garantált. Azt nem tudom az std mennyire tesztelt, de hogy nem átlátható, nem gyors és kellően túl általános az biztos.

   
Instalok - Tag | 619 hsz       Online status #210783   2017.01.09 17:05 GMT+1 óra  
Akkor végső soron jó irányba indultam el, mert én is mallocot használtam. Amit láttam még trükköt az az, hogy void*-ra szokták castolni, mert a new operátor egyébként felülírható, így, ha valaki akkora állat, akkor elronthatja a containert.

Terveztem amúgy én is teljes container-library-t írni, csak meg kell húzni egy egészséges határt. Ott van például a string, meg a különböző type_traits, algoritmusok és a többi. No meg ott a vector, az alapvetően nem (biztos, hogy) annyira rosszul implementált dolog, és legalább jól tesztelt.

Arról nem is beszélve, hogy az std namespace-t nem lehet teljesen kiírtani a kódból egyébként sem. Ott van pl. az std::initializer_list, abból ugyan írhatunk sajátot, csak éppen nem fog működni.

További apróság, hogy std és saját mixeléskor előjönnek a naming convention különbségek. Én például a típusokat (és a függvényeket) upper-camel-case írom, a változókat meg camel-case, míg az std egységesen kisbetűket és underscore-okat használ mindenhol. Persze lehetne követni az std namespace alatti naming convention-t, de az a saját szabályaim félrelökése lenne

   
Asylum - Törzstag | 5504 hsz       Online status #210782   2017.01.09 16:46 GMT+1 óra  
A belső konténerek valóban value_type*-ot használnak adatnak. Ezt azonban nem a new kifejezéssel, hanem malloc()-al foglalják le (így tulajdonképpen típustalan memória marad). Ezek után a placement new az, ami a konkrét konstruktort meghívja:

Kód:
template <typename value_type>
void vector<value_type>::push_back(const value_type& item)
{
    if( mysize >= mycap )
        reserve(mycap + 1);

    new(data + mysize) value_type(item);
    ++mysize;
}


(saját implementáció)
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #210780   2017.01.09 13:26 GMT+1 óra  
Úgy láttam, h a legtöbb esetben, amikor valamilyen konténerbe teszünk elemet, placement new-t használnak, hogy az adott T copy constructora fusson, ne az assignment operatora. Ez igazából nem bug? Adott egy class, ami a default constructorában valamilyen allokálást hajt végre:
Kód:
struct DontDoThis
{
    DontDoThis()
        : arr(new uint8[12])
    {
    }
    DontDoThis(const DontDoThis& other)
        : arr(new uint8[12])
    {
        memcpy(arr, other.arr, 12);
    }
    ~DontDoThis()
    {
        delete[] arr;
    }
   
    uint8* arr;
};

Amikor egy konténer T típusú arrayt használ belső tárolóként, akkor a new T[size] híváskor a T default konstruktora meghívódik. Amikor pedig hív egy push_back(const T&)-t, akkor a placement new meghívja az adott elem copy konstruktorát.
Kód:
template <typename T>
class vector
{
public:
    vector()
        : arr(new T[4]) // T::T() hívások
    {
        end = arr;
    }
   
    void push_back(const T& v)
    {
        ::new (end) T(v); // T::T(const T&)
        ++end;
    }
   
private:
    T* arr;
    T* end;
};

Nem tudom, hogy pontosan így csinálják-e, de ha igen, akkor az nyilván nem jó. Gondolom érdemesebb valami olyan belső reprezentációt választani, ami nem hív default konstruktort (pl. malloc, vagy byte array), vagy nem placement new-t (azaz T copy konstruktort), hanem mondjuk operator= -t használni.

   
Instalok - Tag | 619 hsz       Online status #210764   2017.01.02 22:52 GMT+1 óra  
Ezek szerint ARM-en nincs implicit padding? Csak mert, ha a Header meg a T is paddolva van, akkor elvileg mindig word-boundary-ra esik a cím, nem?

szerk.:
Ahha, mondjuk olyat simán lehet csinálni, hogy a template paraméter egy uint8 lesz, és máris borul az egész, mert akkor a következő Header nem megfelelő címre kerülne.

Ezt a hozzászólást Instalok módosította (2017.01.03 11:48 GMT+1 óra, 988 nap)

   
Asylum - Törzstag | 5504 hsz       Online status #210763   2017.01.02 20:48 GMT+1 óra  
Igen, elő. Pl. ARM-en nagyon kell vigyázni az ilyen kasztolásokkal (pl. volt olyan elszállásom, hogy vector3&-é kasztoltam egy memóriaterületet és a cím invalid lett; szerencsére az xcode elkapta, mint alignment exception).
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Instalok - Tag | 619 hsz       Online status #210762   2017.01.02 19:18 GMT+1 óra  
Adott egy byte buffer, abba szeretnék változó méretű adatokat elhelyezni. Nyilván ehhez egy-egy headert tárolok el az adatok előtt, amivel be lehet azonosítani az adatot és a méretét.
Kód:
--------------------------------------------
header | data | header | data | ...
--------------------------------------------

Eddig nem foglalkoztam alignmenttel, simán csak egymás után pakoltam az adatokat, kb. ilyesmi:
Kód:
template <typename T>
T* Push(IdType id)
{
    // reinterpret_cast
    Header* header = (Header*)&buffer[pos];
    header->id = id;
    header->size = sizeof(T);

    pos += sizeof(Header);   
    T* data = (T*)&buffer[pos];
    pos += sizeof(T);
   
    return data;
}

Ha jól tudom a sizeof() beleszámolja a paddingeket, ami viszont compilerenként/platformonként más és más lehet. Előfordulhat olyan eset/architektúra, hogy a fenti kód nem fog jól működni?

   
Matzi - Szerkesztő | 2528 hsz       Online status #210712   2016.12.20 20:52 GMT+1 óra  
Atomical lehet meg lehetne oldani tobbszálú esetben is a mukodést. Esetleg csinálj egy olyat, hogy statikusan inicializálsz példányokat, és még nevet is adsz neki. Lényegében egyfajta szegény ember RTTI-je, ami ugyan nem jó minden típusra, de úgysem kell hogy jó legyen minden típusra.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
   
Instalok - Tag | 619 hsz       Online status #210711   2016.12.20 19:39 GMT+1 óra  
Inline nélkül multiple definition.

Az ilyen egyszerű trükkök (mint pl. egy static counter) pedig ugye problémásak lehetnek, amint 1-nél több szál van a dologban. Lehetne még esetleg a preprocesszorral szórakozni, de az sem az igazi. Nem akarok csak ezért RTTI-t használni, az annyira gáz.

   
Matzi - Szerkesztő | 2528 hsz       Online status #210706   2016.12.20 12:32 GMT+1 óra  
Konnyen megeshet, hogy ez megtorténik. http://stackoverflow.com/questions/2175302/unique-numerical-id-for-a-templated-class-using-function-address
"I tested this with VS 2015 and it works when compiling for Debug but not when compiling for Release. When compiling for Release, the optimizer combines all classID() functions into a single one."

Az sem jelent sok jót, hogy inline-osítottad. Ha inline lesz, akkor a fuggvény nem is létezik, szóval nem is nagyon lesz címe. Valószínuleg ebben az esetben inkább csak figyelmen kívul hagyja az inline-t.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
   
Instalok - Tag | 619 hsz       Online status #210705   2016.12.20 09:11 GMT+1 óra  
Régebben olyan megoldást választottam egy típus azonosítására, hogy:
Kód:
template <typename T>
class IdGenerator
{
public:
    static uint64 Get();
};

template <typename T>
inline uint64 IdGenerator<T>::Get()
{
    return reinterpret_cast<uint64>(&Get);
}

De most kicsit elbizonytalanodtam: mi történik, ha a fordító ügyeskedik, és nekiáll bőszen optimalizálni. Megtörténhet az, hogy az összes függvény tulajdonképpen ugyan az lesz (ezzel elveszítve a címuk egyediségét)? Igazából elvileg megtörténhet, mert maga a függvény nem (és az osztály sem) függ a T-től.

   
gopher - Törzstag | 497 hsz       Online status #210673   2016.12.15 15:05 GMT+1 óra  
@Geri:

Cities: Skylines
Dead Effect 2
Ori and the Blind Forest
Lara Croft: Relic Run
..és a sor bőven folytatható. Teljesen más a Unity, mint egy Game Maker, és kár úgy fikáznod valamit, hogy sosem próbáltad ki. A labda pattintgatós játékból meg kihagyod, hogy mostanában nem elég hogy megcsinálod a játékot, nem árt ha ez fut Android/iOS kombón és eléri az adott platform service-ait (pl. Play Services, Admob). Ami Unity-ben egy-egy plugin, illetve egy-egy klikk a build, míg ezt only C-ben elég sokáig fog tartani összehozni.

@Matzi: sorry, ezt közben írtam. De Geri, válaszolj az általános topicban

Ezt a hozzászólást gopher módosította (2016.12.15 16:15 GMT+1 óra, 1007 nap)
   
Matzi - Szerkesztő | 2528 hsz       Online status #210672   2016.12.15 14:54 GMT+1 óra  
Ezzel át lehet menni az Általános Offtopicba.
If your game idea starts with the story it’s not a game idea.
Stories in games are optional.
   
Parallax - Tag | 609 hsz       Online status #210671   2016.12.15 14:41 GMT+1 óra  
Igen pont arról volt szó, hogy nem programozók fejlesztenek, már amennyire a pár soros fgv alapú scriptelést, meg a visual scriptinget a nem programozók csoportjának tekintjük. Szóval igen, nekik már az is sok, hogy van egy engine/lib, amit le kell fordítani forrásból, esetleg linkelni, vagy kódolni C/C++ ban, ezt mint negatívumot hozzák fel már kapásból és már nem is foglalkoznak vele. Még a "maker" motoroknál is kifogás, ha nem elég egyszerű a használata a közel 0 programozás mellett is, nincsen mondjuk match3, vagy booble template, hanem dokumentációkat kell olvasni (phejj). Hátrány, hogy egy Hello alkalmazás is 200 mb és nyilván szuboptimális lesz az eredmény egy sokféle igénynek megfelelő motorral, egy adott célra kifejlesztettel szemben.

Most a JF azt a korszakát éli, ami az üzleti szoftvereknél volt a 90-es években. Szakértői rendszerek, vizuális fejlesztői eszközök voltak, ahol pár kattintással szinte 0 programozással lehetett létrehozni alkalmazásokat. (Progress, Magic stb.) Aztán rájöttek, hogy egyéni igényeknek nem lehet megfelelni ilyen "maker" eszközökkel és ma már még a felhasználói felületet is programozással kell létrehozni (lásd WPF). Szóval majd lehet a JF is túljut ezen az időszakon, ha lesz rá igény, ki tudja.

   
Geri - Törzstag | 2198 hsz       Online status #210670   2016.12.15 14:17 GMT+1 óra  
szerintem egyszerűen arról van szó, hogy parallax, szerintem egy valamihez hozzá kell pattintani egy labdát jellegű játékot egyszerűbben megcsinálsz mondjuk C-ben mint bármi másban pusztán azért, mert C/c++-ban szabadabban és nagyon gyorsan meg tudod csinálni hozzá az azt hajtó logikát és koordinátageometriát, míg mondjuk egy librarykból összedobált szkriptelőtool erre nem biztos, hogy alkalmas pusztán azért, mert ha ehhez a logikához valami épp nincs leimplementálva mellé, akkor egy ilyen környezetben erősen valószínű, hogy érdemben nem is fogod tudni leimplementálni. mivel a c# a statok szerint már halott, mondjuk előlegezzük meg, hogy egy ilyen tetszőleges toolban is vagy C-vel, c++-al, vagy esetleg javaval, basiccel, vagy a tool saját nyelvével kell majd dolgozni eleve, tehát ebből a szempontból nincs különbség. egy alapvető engine néhány ezer sor valamilyen tetszőleges apira építve (de ha meg valaki vadállat eléggé, az is megvan 2ezerrel több sorból, ha nagyon akarja), és akkor az tud már keyframe animot, meg alapvető effekteket is, elég mondjuk 10 évente újat írni belőle. középiskolás mateknál sem kell sehová több. tehát nem egy olyan traumatikus programozási probléma, amit el kell kerülni. a munkának talán 1-2%-át teszi ki, az adott játékban lévő kódnak talán 5-10%-át. a többi meg mondjuk az engine azon része, ami már a konkrét játékot vezérli - pl fps esetén egy fps logic ami irányítja az npc-ket, a fegyverek lövéseit, meg mondjuk azt, hogy a falon ne sétálj át, meg a töltény se mindenhol menjen át. tehát egyszerűen arról van szó, hogy aki ezt is le akarja spórolni arra hivatkozva, hogy milyen bonyolult, az általában nem egy rendes programozó, de még csak nem is egy rendes játékfejlesztő, ugyanis az engine magjának a leimplementálása több nagyságrenddel egyszerűbb, mint mondjuk felhúzni egy pokemon-rpg harcrendszert. ha az első nem megy neki, akkor a második sem fog. hogy akar egy 40ezer soros battle logicot lekódolni, ha az 5 ezer soros enginetől összefossa magát valaki, hogy az milyen bonyolult? sehogy. ezzel nem spórol sem időt, se semmit, csak a világ felé teszi a szépet, hogy ő milyen király, meg hogy mennyit haladt, és hogy már wasd-vel lehet repkedni benne, ő itt a király. így aztán a kezei közül kikerülő alkotások is szarok, mint ahogy mondjuk unity kapcsán látjuk a sok hulladékot. az eredmény aztán nem komolyan vehető, nem eladható, nem továbbfejleszthető, 10x nagyobb, 5x annyi erőforrást használ, tud pár ezer letöltést és max 40 eladást, azok is a haverjai a fórumokról... vannak persze jó enginek, csak azok eléggé célirányosak szoktak lenni, nem ilyen toolcopy, szintűek, de ha valaki ténylegesen alkotni akar valamit, akkor azokat is érdemes hanyagolni.

ma már olyan egyszerűen meg lehet írni bármit normálisan, hisz az internet korát éljük, kontrasztban mondjuk 1995-el és 2000-el, amikor még csak 1-2 embernek volt internetje, semmiről nem lehetett semmit sem tudni, egy pixelt sem lehetett kirajzolni, mert minden információ rejtve és titkolva volt, hogy egyszerűen nincs értelme annak, hogy thirdparty toolokkal akadályozza az ember saját magát.

   
Lord_Crusare - Törzstag | 1324 hsz       Online status #210669   2016.12.15 10:55 GMT+1 óra  
Csak az első.

A másodikat már az Obsidian fejlesztette:

http://store.steampowered.com/search/?developer=Obsidian%20Entertainment

   
Asylum - Törzstag | 5504 hsz       Online status #210668   2016.12.15 10:49 GMT+1 óra  
Hé, a KOTOR az Bioware!

(nem?)
C++ fordítóval és macival alszom
http://darthasylum.blog.hu/
   
Frissebbek | Korábbi postok
[1] > 2 < [3] [4] [5] [6] [7] [8] [9] [10] [15] [20] [25] [30] [35] [40] [45] [50] [55] [60] [65] [70] [75] [80] [85] [90] [95] [100] [105] [110] [115] [120] [125] [130] [135] [140] [143]