рдХреМрди рддреЗрдЬ рд╣реИ: рдореЗрдорд╕реЗрдЯ, рдмреЗрдЬрд╝реЗрд░реЛ рдпрд╛ рдПрд╕рдЯреАрдбреА :: рдлрд┐рд▓

рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ std :: fill () рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╕рд░рд▓ рдкреБрд░рд╛рдиреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрд╢рд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдЕрдЪреНрдЫрд╛ рдкреБрд░рд╛рдирд╛ рдореЗрдорд╕реЗрдЯ () (рдЪреВрдВрдХрд┐ рдпрд╣ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред

рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рд╕рдм рдХреБрдЫ рдЙрддрдирд╛ рдкрд╛рд░рджрд░реНрд╢реА рдирд╣реАрдВ рд╣реЛрддрд╛ рдЬрд┐рддрдирд╛ рд╣рдо рдЪрд╛рд╣реЗрдВрдЧреЗред рдХрд╛рд░реНрдпрдХреНрд░рдо рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред


#include <cstdlib> #include <algorithm> int main(int argc, char* argv[]) { int mode = argc > 1 ? std::atoi(argv[1]) : 1; int n = 1024 * 1024 * 1024 * 1; char* buf = new char[n]; if (mode == 1) std::memset(buf, 0, n * sizeof(*buf)); else if (mode == 2) bzero(buf, n * sizeof(*buf)); else if (mode == 3) std::fill(buf, buf + n, 0); else if (mode == 4) std::fill(buf, buf + n, '\0'); return buf[0]; } 

рд╢рд╛рдЦрд╛рдУрдВ 3 рдФрд░ 4 рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рд╡реЗ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд╛рдлреА рдирд╣реАрдВред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рднрд░рдиреЗ рдХреА рдЗрд╕ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдЪрд╛рд░ рдерд╛:

 // Specialization: for one-byte types we can use memset. inline void fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) { __glibcxx_requires_valid_range(__first, __last); const unsigned char __tmp = __c; std::memset(__first, __tmp, __last - __first); } 

рддреЛ рдореЗрдХрдлрд╛рдЗрд▓:

 all: build run .SILENT: target = memset_bzero_fill build: g++ -O3 -o $(target) $(target).cpp run: run-memset run-bzero run-fill-1 run-fill-2 go: (time -p ./$(target) $(mode)) 2>&1 | head -1 | cut -d' ' -f 2 run-memset: echo $@ `$(MAKE) go mode=1` run-bzero: echo $@ `$(MAKE) go mode=2` run-fill-1: echo $@ `$(MAKE) go mode=3` run-fill-2: echo $@ `$(MAKE) go mode=4` 

рдХрдВрдкрд╛рдЗрд▓рд░ "gcc рд╕рдВрд╕реНрдХрд░рдг 4.2.1 (Apple Inc. build 5666) (dot 3)ред"

рд╣рдо рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ:

  run-memset 1.47 run-bzero 1.45 run-fill-1 1.69 run-fill-2 1.42 

рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рд╢рд╛рдЦрд╛ 3 (рд░рди-рдлрд┐рд▓ -1) 4 рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдзреАрдорд╛ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдЕрдВрддрд░ рдХреЗрд╡рд▓ 0 рдФрд░ '\ 0' рд╣реИред

рд╣рдо рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:

 (gdb) disass main Dump of assembler code for function main: 0x0000000100000e70 <main+0>: push %rbp 0x0000000100000e71 <main+1>: mov %rsp,%rbp 0x0000000100000e74 <main+4>: push %r12 0x0000000100000e76 <main+6>: push %rbx 0x0000000100000e77 <main+7>: dec %edi 0x0000000100000e79 <main+9>: jle 0x100000ec3 <main+83> 0x0000000100000e7b <main+11>: mov 0x8(%rsi),%rdi 0x0000000100000e7f <main+15>: callq 0x100000efe <dyld_stub_atoi> 0x0000000100000e84 <main+20>: mov %eax,%r12d 0x0000000100000e87 <main+23>: mov $0x40000000,%edi 0x0000000100000e8c <main+28>: callq 0x100000ef8 <dyld_stub__Znam> 0x0000000100000e91 <main+33>: mov %rax,%rbx 0x0000000100000e94 <main+36>: cmp $0x1,%r12d 0x0000000100000e98 <main+40>: je 0x100000eac <main+60> ; mode == 1 0x0000000100000e9a <main+42>: cmp $0x2,%r12d 0x0000000100000e9e <main+46>: je 0x100000eac <main+60> ; mode == 2 0x0000000100000ea0 <main+48>: cmp $0x3,%r12d 0x0000000100000ea4 <main+52>: je 0x100000ed2 <main+98> ; mode == 3 0x0000000100000ea6 <main+54>: cmp $0x4,%r12d 0x0000000100000eaa <main+58>: jne 0x100000ebb <main+75> ; mode != 4 ->  ;   memset(). 0x0000000100000eac <main+60>: mov $0x40000000,%edx ; mode = 1, 2  4 0x0000000100000eb1 <main+65>: xor %esi,%esi 0x0000000100000eb3 <main+67>: mov %rbx,%rdi 0x0000000100000eb6 <main+70>: callq 0x100000f0a <dyld_stub_memset> 0x0000000100000ebb <main+75>: movsbl (%rbx),%eax ;  0x0000000100000ebe <main+78>: pop %rbx 0x0000000100000ebf <main+79>: pop %r12 0x0000000100000ec1 <main+81>: leaveq 0x0000000100000ec2 <main+82>: retq 0x0000000100000ec3 <main+83>: mov $0x40000000,%edi 0x0000000100000ec8 <main+88>: callq 0x100000ef8 <dyld_stub__Znam> 0x0000000100000ecd <main+93>: mov %rax,%rbx 0x0000000100000ed0 <main+96>: jmp 0x100000eac <main+60> ;    . 0x0000000100000ed2 <main+98>: movb $0x0,(%rax) ; mode = 3 0x0000000100000ed5 <main+101>: mov $0x1,%eax 0x0000000100000eda <main+106>: nopw 0x0(%rax,%rax,1) 0x0000000100000ee0 <main+112>: movb $0x0,(%rax,%rbx,1) 0x0000000100000ee4 <main+116>: inc %rax 0x0000000100000ee7 <main+119>: cmp $0x40000000,%rax 0x0000000100000eed <main+125>: jne 0x100000ee0 <main+112> 0x0000000100000eef <main+127>: movsbl (%rbx),%eax ;  0x0000000100000ef2 <main+130>: pop %rbx 0x0000000100000ef3 <main+131>: pop %r12 0x0000000100000ef5 <main+133>: leaveq 0x0000000100000ef6 <main+134>: retq 

рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЕрдиреБрдХреВрд▓рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╢рд╛рдЦрд╛рдУрдВ 1, 2 рдФрд░ 4 рдХреЛ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдореЗрдорд╕реЗрдЯ () рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред рд╢рд╛рдЦрд╛ 4 рдореЗрдВ рднрд░рд╛ () рдХреЙрд▓ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП () рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рд▓реЗрдХрд┐рди рд╢рд╛рдЦрд╛ 3 рдХреЛ рдПрдХ рдореИрдиреБрдЕрд▓ рдЪрдХреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рдВрдХрд▓рдХ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдПрдХ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ - рдЪрдХреНрд░ рд▓рдЧрднрдЧ рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдЪрд╛рд▓рд╛рдХ рдореЗрдорд╕реЗрдЯ () рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рдореВрд╣ рдХреЛрдбрд╛рдВрддрд░рдХ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╢реВрдиреНрдп рдиреЗ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЪреБрдирдиреЗ рд╕реЗ рд░реЛрдХ рджрд┐рдпрд╛ред

рдиреИрддрд┐рдХ? рдФрд░ рдпрд╣рд╛рдБ рдиреИрддрд┐рдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред

рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ "std :: fill (buf, buf + n, 0)" рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ "std :: fill (buf, buf + n, '\ 0') рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИред"

рдФрд░ рдЕрдВрддрд░ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

Source: https://habr.com/ru/post/In118716/


All Articles