最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

memory management - Why is copying more efficient in Zig remap? - Stack Overflow

programmeradmin1浏览0评论

The remap function in Zig's memory allocator interface is supposed to "attempt to expand or shrink memory, allowing relocation". In particular, it mentions that...

A null return value indicates that the resize would be equivalent to allocating new memory, copying the bytes from the old memory, and then freeing the old memory. In such case, it is more efficient for the caller to perform the copy.

I don't understand the claim that it is more efficient to perform a copy. If I want to copy some block of memory, I will have to allocate some new memory, copy the bytes over and (eventually) free the old block anyways. So what efficiency am I gaining?

The only thing I can think of is if I already have an already allocated block of memory that I can reuse for copying in which case I avoid the allocation step.

The remap function in Zig's memory allocator interface is supposed to "attempt to expand or shrink memory, allowing relocation". In particular, it mentions that...

A null return value indicates that the resize would be equivalent to allocating new memory, copying the bytes from the old memory, and then freeing the old memory. In such case, it is more efficient for the caller to perform the copy.

I don't understand the claim that it is more efficient to perform a copy. If I want to copy some block of memory, I will have to allocate some new memory, copy the bytes over and (eventually) free the old block anyways. So what efficiency am I gaining?

The only thing I can think of is if I already have an already allocated block of memory that I can reuse for copying in which case I avoid the allocation step.

Share Improve this question asked 2 days ago wildcatwildcat 711 silver badge4 bronze badges 1
  • remap isn't in any actual Zig release yet. It was checked into the master branch two days ago. There's no guarantee the final design will actually work like this, or that it'll even make it into the next Zig release at all. – user2357112 Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 1

remap is not in any actual Zig release yet. It was checked into the master branch 2 days ago. It may not actually make it into any actual release.

That said, looking at the uses of remap that were introduced in the same commit, we can see the kinds of cases that motivated this interface. The idea is that the caller can't perform the alloc/copy/free sequence more efficiently than remap, but it might not want to do that specific alloc/copy/free sequence anyway.

For example, in array_list.zig, under addManyAt:

            const new_capacity = growCapacity(self.capacity, new_len);
            const old_memory = self.allocatedSlice();
            if (self.allocator.remap(old_memory, new_capacity)) |new_memory| {
                self.items.ptr = new_memory.ptr;
                self.capacity = new_memory.len;
                return addManyAtAssumeCapacity(self, index, count);
            }

            // Make a new allocation, avoiding `ensureTotalCapacity` in order
            // to avoid extra memory copies.
            const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
            const to_move = self.items[index..];
            @memcpy(new_memory[0..index], self.items[0..index]);
            @memcpy(new_memory[index + count ..][0..to_move.len], to_move);
            self.allocator.free(old_memory);

If the remap can proceed without a copy, it does. Otherwise, the code allocates a new buffer, but it separately copies the parts of the original buffer before and after index into the parts of the new buffer they need to go in. It also avoids copying any undefined space at the end of the old buffer, between the old length and capacity.

发布评论

评论列表(0)

  1. 暂无评论