Today I learned - Share your newly found knowledge!
#81

OK, I didn't mention that I'm not allocating small blocks from the heap - I just allocate one huge (several Mb) block once, then allocate from within there. I don't have benchmarks; I can get some but I'm not sure what you want benchmarking - the "malloc" function? Because of the way the code works, actually using the allocated memory is just the same as a standard array access and an addition.

As for fragmentation, that is an issue I've not been able to deal with because I'm currently using direct pointers rather than indirect ones. I could change model and then I could do compression and just update the indirection array, but obviously then you have more code involved (I could make it an option I suppose). The allocation algorithm is the most basic one too - it just allocates from the first free block of sufficient size, there is also "smallest" and "largest", which allocate from the closest matching or most free blocks - it would be interesting to see how they affect fragmentation. "free" is clever though and can merge adjacent blocks when they are both free to give a larger block from which to allocate.
Reply
#82

Very crafty. Nice!

I'd suggest you make it so each library could tell y_malloc how much memory it wants, then it'd be added up and "stolen" on startup.
That way each library could worry about its own, and get all the memory it wants.

pawn Код:
#define MALLOC_SPACE_WANTED 10485760
#include <ysi\y_malloc>
#define MALLOC_SPACE_WANTED (MAX_SOMETHING * 1024)
#include <ysi\y_malloc>
Reply
#83

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
OK, I didn't mention that I'm not allocating small blocks from the heap - I just allocate one huge (several Mb) block once, then allocate from within there. I don't have benchmarks; I can get some but I'm not sure what you want benchmarking - the "malloc" function? Because of the way the code works, actually using the allocated memory is just the same as a standard array access and an addition.

As for fragmentation, that is an issue I've not been able to deal with because I'm currently using direct pointers rather than indirect ones. I could change model and then I could do compression and just update the indirection array, but obviously then you have more code involved (I could make it an option I suppose). The allocation algorithm is the most basic one too - it just allocates from the first free block of sufficient size, there is also "smallest" and "largest", which allocate from the closest matching or most free blocks - it would be interesting to see how they affect fragmentation. "free" is clever though and can merge adjacent blocks when they are both free to give a larger block from which to allocate.
Benchmarks with the older version of `malloc`. Anyway, I think this is one is a little slower than the older one.

Can people allocate more memory than those "several Mb"?
Reply
#84

Quote:
Originally Posted by Slice
Посмотреть сообщение
Very crafty. Nice!

I'd suggest you make it so each library could tell y_malloc how much memory it wants, then it'd be added up and "stolen" on startup.
That way each library could worry about its own, and get all the memory it wants.

pawn Код:
#define MALLOC_SPACE_WANTED 10485760
#include <ysi\y_malloc>
#define MALLOC_SPACE_WANTED (MAX_SOMETHING * 1024)
#include <ysi\y_malloc>
I'm not sure that's possible when using "#pragma dynamic".

Quote:
Originally Posted by Dan..
Посмотреть сообщение
Benchmarks with the older version of `malloc`. Anyway, I think this is one is a little slower than the older one.

Can people allocate more memory than those "several Mb"?
No, but you can tell it to allocate more initially.

Edit: It turns out I missed something very important. Once I was done with the code I removed all the debug prints and it instantly stopped working! I'm still not 100% sure of the issue, but I think it might be this in amx.c:

pawn Код:
case OP_SYSREQ:
    GETPARAM(offs);
    /* save a few registers */
    amx->cip=(cell)((unsigned char *)cip-amx->code);
    amx->hea=hea;
    amx->frm=frm;
    amx->stk=stk;
Pretty sure that saves something important for my code, and once I removed "print" I removed the call to it.
Reply
#85

Today I learned that if you add OnGameModeInit() and OnGameModeExit() to your filterscript, and you load this script as a filterscript, both those callbacks will be called at the appropriate times when using /rcon gmx.

I always thought these callbacks only worked inside a gamemode.
Reply
#86

Today I learned how you can easily check if a variable being used to loop through an array has reached the end of the array, and reset it if it has.

Example:
pawn Код:
index++;
if(index >= sizeof(array)) {
    index = 0;
}
// do something with array[index]
would become:

pawn Код:
index++;
index %= sizeof(array);

// do something with array[index]
Reply
#87

Today I learned why this problem exists:

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
Edit: It turns out I missed something very important. Once I was done with the code I removed all the debug prints and it instantly stopped working! I'm still not 100% sure of the issue, but I think it might be this in amx.c:

pawn Код:
case OP_SYSREQ:
    GETPARAM(offs);
    /* save a few registers */
    amx->cip=(cell)((unsigned char *)cip-amx->code);
    amx->hea=hea;
    amx->frm=frm;
    amx->stk=stk;
Pretty sure that saves something important for my code, and once I removed "print" I removed the call to it.
I was basing all my code on the source code for the 3.2.3664 build of PAWN as that's what the compiler reports. However, I had a brainwave and remembered that I had upgraded the compiler independently from the VM when I was a dev, so I got the 3.0.3367 source code and discovered that it was missing these two important lines from the "op_halt" code:

pawn Код:
amx->frm=frm;
amx->stk=stk;
Which entirely explains why it broke when I didn't call "SYSREQ" first.
Reply
#88

"," and ";" mean different things - make sure you read the documentation on what the differences actually are or your code may not do what you think.
Reply
#89

Quote:
Originally Posted by pds2012
Посмотреть сообщение
Today I learned that function could be divided with ,(comma) without using spaces, Example code below.

pawn Код:
TogglePlayerSpectating(playerid, 1), SendClientMessage(playerid, -1, "Spectating Mode");
Instead of
pawn Код:
TogglePlayerSpectating(playerid, 1);
SendClientMessage(playerid, -1, "Spectating Mode");
I've been scripting since December 2011, I just knew this
It's called having multiple functions in one line, so it appears as one statement.

https://sampforum.blast.hk/showthread.php?tid=216730

TIL that:

pawn Код:
enum myEnum
{
    propertyA,
    propertyB,
    propertyC
}
new MyEnum[myEnum];
myEnum equals 3 (propertyA = 0, propertyB = 1, propertyC = 2). 2 + 1 = 3.

pawn Код:
enum myEnum (+= 4)
{
    propertyA,
    propertyB,
    propertyC
}
new MyEnum[myEnum];
myEnum equals 12 (propertyA = 0, propertyB = 4, propertyC = 8). 8 + 4 = 12.

Pretty interesting stuff, I'm still learning the basics of #emit, but I didn't know this. :D
Reply
#90

Not quite. Try this:

pawn Код:
#include <a_samp>

enum A(+=4) {
    B,
    C,
    D,
    E,
    F
}

main() {
    printf("%d", _:A);
}
Reply
#91

Today I learned how to craete an "inverted" loop by that I mean it starts for example from 300 and goes down.
pawn Код:
for(new i=2;i<13;i++)
    {
        format(FdStr[i-12],55,"%s",FdStr[i-11]);
        TextDrawSetString(FeedBox[i-12],FdStr[i-12]);
    }
Reply
#92

Err - no you didn't!

pawn Код:
for (new i = 10; i != 0; --i)
Or as most people would write it:

pawn Код:
for (new i = 10; i >= 0; i--)
Note that you have to be MUCH more careful with OBOEs (Off By One Errors) with downwards loops - that code above will run 11 times, including for index 10, which will cause errors if any arrays re of size 10. An alternate way that avoids this issue is:

pawn Код:
for (new i = 10; --i != 0; )
pawn Код:
for (new i = 10; --i >= 0; )
pawn Код:
for (new i = 10; i-- > 0; )
Those are all equivalent, and will run from 9 to 0 (inclusive).
Reply
#93

I didnt even think about mkaing it that way :/ well I still learned something learned that I make quite a lot of mistakes.
Reply
#94

Your way doesn't even work - it counts up from -10 to 0.
Reply
#95

Today I learnt how to deal with OBOEs thanks to Y_Less.

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
Note that you have to be MUCH more careful with OBOEs (Off By One Errors) with downwards loops - that code above will run 11 times, including for index 10, which will cause errors if any arrays re of size 10. An alternate way that avoids this issue is:

pawn Код:
for (new i = 10; --i != 0; )
pawn Код:
for (new i = 10; --i >= 0; )
pawn Код:
for (new i = 10; i-- > 0; )
Those are all equivalent, and will run from 9 to 0 (inclusive).
Awesome, I like this.

Today I really learnt some stuff about queue's (not really pawn related)

http://en.wikipedia.org/wiki/Queue_management_system
http://en.wikipedia.org/wiki/Queueing_theory
http://en.wikipedia.org/wiki/Queueing_delay

http://en.wikibooks.org/wiki/A-level...oncepts/Queues

I don't think this is what I really wanted though.

I couldn't really find much other sites other than wikipedia.. hopefully someone can link me.
Reply
#96

You could try the STL queue documentation:

http://www.cplusplus.com/reference/queue/queue/
Reply
#97

Today I learned that you can do some numeric operations on arrays, which alters the address given. So far I haven't found anything useful with it, but you can do this:
pawn Код:
print(-~~-"hello");
Edit:
This could be used to make pointers:
pawn Код:
stock g_ptrarr[1000];

#define @ptr[%1] \
    (!~g_ptrarr)[%1 / 4]

main() {
    new address = ref("hello"); // ref gets the address of the argument
   
    print(@ptr[address]);
}
The only remaining problem is runtime BOUNDS checks, which can be NOPed at startup!!

BTW, thanks to Emmet_ for accidentally find this: http://forum.sa-mp.com/showthread.ph...20#post2738320
Reply
#98

Today I learned how to reset an enum easily, and using @ to declare public functions:

Easy Enumerator reset
pawn Код:
enum EnumeratorInformation
{
    EnumNum1,   EnumNum2,
    EnumNum3,   EnumNum4
}
new
    EnumInfo [ EnumeratorInformation ]
;

CMD:easyenumreset(playerid, params[])
{
    for(new i; EnumeratorInformation:i < EnumeratorInformation; i++)  { EnumInfo [ EnumeratorInformation:s ] = 0; }
    return 1;
}
declaring public functions using @
pawn Код:
forward @GetTodaysDate();
@GetTodaysDate()
{
    new
        dString[ 18+2 ],
        Date[ 6 ]
    ;
            //Year      //Month     //Day
    getdate(Date[ 0 ], Date[ 1 ], Date[ 2 ]);
            //Hour      //Minutes   //Seconds
    gettime(Date[ 3 ], Date[ 4 ], Date[ 5 ]);

    format(dString, sizeof (dString), "%d/%d/%d %d:%d:%d", Date[ 2 ], Date[ 1 ], Date[ 0 ], Date[ 3 ], Date[ 4 ], Date[ 5 ]);
    return dString;
}
Reply
#99

Today I learned how to use the '%' operator!
Reply

Quote:
Originally Posted by SsHady
Посмотреть сообщение
Today I learned how to use the '%' operator!
Come on, man, I even made a red arrow.

Quote:
Originally Posted by FIRST POST
Please:
  • Explain what it is you learned, don't just say you learned something. <----
Reply


Forum Jump:


Users browsing this thread: 14 Guest(s)