Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: the way to probably speed up sfml's image loading  (Read 4853 times)

0 Members and 1 Guest are viewing this topic.

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
the way to probably speed up sfml's image loading
« on: July 28, 2015, 12:08:12 pm »
Once upon a time i was diving on SFML 2.3.1 source code and i found the image loading function and i saw the std::vector usage for holding bytes of image. I think that std::vector must be replaced with somothing else  :) because the std::vector works like that: when user calls push_back, it causes:
1.)the old data becomes buffer that holds previous values;
2.)than he creates new memory (calls new[size wich is 1 more bigger than previous]), that is empty,
3.) than he fills new memory with buffer's data, than removes the buffer from memory,
4.)and than initilizates the new, empty element of new memory with value that was an argument for push_back() function.

speeking shortly: the std::vector::push_back() function causes the hard allocation and dellocation of memory process. And as we know most of images have in average 1000 bytes inside (or more)!
Example: that std::vector allocates new 1000 bytes in memory than fills it from buffer that has (logically) 999 bytes with which it Fills the new memory(as i know it fills new memory with some kind of loop, maybe
for(...){}
) than removes the buffer(removes 999 bytes!) and than initilizates the new element with push_back() function argument.
Sounds terrible!!!

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #1 on: July 28, 2015, 12:44:56 pm »
I don't know if i am allowed to place sfml-source here but here is what i don't undertstand
(click to show/hide)

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #2 on: July 28, 2015, 12:52:32 pm »
std::vector's size() increases by one when you do push_back() but the capacity() increases by much more (commonly doubles). So pushing 1000 elements into a vector does not result in 1000 allocations (since that would be terrible).
If the final size of the vector is known up-front, then you can call reserve() on the vector first to pre-allocate all the memory.
In short: a vector is just fine for something like this.

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #3 on: July 28, 2015, 12:54:30 pm »
But i still does not understand why must we store image data in std::vector if STB image libray already gives us pointer to full acesses array of pixels after finishing loading.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 878
    • View Profile
Re: the way to probably speed up sfml's image loading
« Reply #4 on: July 28, 2015, 01:44:48 pm »
You misunderstood the code. :)

The function quoted by you uses a std::vector<Uint8> by reference to pass the loaded image data. This is essentially one C++ way to pass "allocated" memory without knowing the required size beforehand.

Since the required memory is reserved in advance (by calling sf::Vector::resize()), there's only one reallocation (if at all).

This vector will never hold more than one image at a time and the contents are assigned at one time only (the memcpy() line). So the (indeed) expensive reallocation upon adding elements essentially never happens.

The only point I see, which might essentially cause some minor thing, is the actual call to std::vector::resize(), since I'm not 100% sure how it changes the reserved size (might stay the same or could double).

The reason for storying the image data "twice" is the fact that the original pixels array returned by stbi is owned by stbi. Essentially copying that data and freeing the stbi owned memory is just one way to better be able to track the image data in a constant way (remember: the image data might be loaded in some other way without stbi, so there isn't always memory allocated by stbi).
« Last Edit: July 28, 2015, 01:47:56 pm by Mario »

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #5 on: July 28, 2015, 03:08:58 pm »
But still the code as I know isn't the fastest as it could be in some cases :).

First of all the mecpy function makes binary coping, that means bit by bit. I think that is awful  :(.

Secondly there is way to make more fast way - this is using dynamic memory and there is a way to store the size of array without the std:vector - this formula is inside code that I posted:
width * height * 4
So I think that it would be released like that:
1.) copy the data from stb image array to another using new[width * height * 4]
2.) using same formula for memory reserving store the size of array
width * height * 4
So we get a simple structure for holding image
struct ImageData{
     sf::Uint8* data; //pointer to allocated data-array
     size_t size; //number of elements in array(width * height * 4)
};
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #6 on: July 28, 2015, 03:20:03 pm »
I don't mean to be rude, but please don't talk about things that you don't know. I could take all your points and prove how they are wrong, but I haven't got the time right now. Maybe someone will be kind enough to do it nicely.
Laurent Gomila - SFML developer

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #7 on: July 28, 2015, 03:20:10 pm »
First of all the mecpy function makes binary coping, that means bit by bit. I think that is awful  :(.
Have you ever taken a look at an optimized implementation of memcpy? I'm guessing no - if you had, you'd know that it does not naively copy bit-by-bit or even byte-by-byte. You can't beat memcpy for speed (I'd like to see you try at least).
« Last Edit: July 28, 2015, 03:42:00 pm by Jesper Juhl »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: the way to probably speed up sfml's image loading
« Reply #8 on: July 28, 2015, 05:13:37 pm »
Secondly there is way to make more fast way - this is using dynamic memory and there is a way to store the size of array without the std:vector
[...]
So I think that it would be released like that:
1.) copy the data from stb image array to another using new[width * height * 4]
[...]
I find it odd that you're complaining about the data being copied and then suggest a "faster" version "using dynamic memory" which copies the data.
It looks like you have a personal vendetta against std::vector (maybe against all of STL?) as you suggest doing the same thing using a raw pointer instead. Firstly, there are much safer pointers to use. Secondly, a vector uses memory in the same way that an array does. Its elements are laid out contiguously. Therefore, a pointer to the first element of a vector is identical to a pointer to the first element in a array that stores the same data.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: the way to probably speed up sfml's image loading
« Reply #9 on: July 28, 2015, 10:17:59 pm »
Oh sorry.  :-\
No i see that whole post looks supid  :) thank for Hapax and others for explaning it.