5 Kasım 2022 Cumartesi

std::views::split metodu

Giriş
Şu satırı dahil ederi
#include <iomanip>
#include <iostream>
#include <ranges>
#include <string>
#include <string_view>
Örnek - char
Şöyle yaparız
using namespace std::literals;

// returns the splitted string
auto splittedWords3 = std::views::split("one:two:three", ':');
for (const auto word : splittedWords3)
  std::cout << std::quoted(std::string_view(word));
Örnek - string
Açıklaması şöyle Yani string literal ile dikkatli olmak lazım
String literals always end with a null-terminator, so ":.:" is actually a range with the last element of \0 and a size of 4.

Since the original string does not contain such a pattern, it is not split.
Şöyle yaparız
using namespace std::literals;

// returns the original string (not splitted)
auto splittedWords1 = std::views::split("one:.:two:.:three", ":.:");
for (const auto word : splittedWords1)
  std::cout << std::quoted(std::string_view(word));
    
std::cout << std::endl;

// returns the splitted string
auto splittedWords2 = std::views::split("one:.:two:.:three", ":.:"sv);
for (const auto word : splittedWords2)
  std::cout << std::quoted(std::string_view(word));
    
std::cout << std::endl;

// returns the original string (not splitted)
auto splittedWords4 = std::views::split("one:two:three", ":");
for (const auto word : splittedWords4)
  std::cout << std::quoted(std::string_view(word));

26 Nisan 2022 Salı

std::empty

Giriş
std::enpty() aslında kendisine verilen container nesnesinin empty() metodunu çağırır. Metodun için şöyle
template <class C>
constexpr auto empty(const C& c) -> decltype(c.empty()); 
// (since c++17, until c++20)

template <class C>
[[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty());
(since C++20) // (since c++20)

Öyleyse std::empty neden var ? Açıklaması şöyle
std::empty is useful for scenarios where a container may or may not provide a member function empty() for types providing a member function empty, std::empty provides a default implementation, but for a custom type not providing this function you can provide a function empty at namespace scope for use in templates; thanks to argument dependent lookup the function in the same namespace as the parameter will be used as fallback
Örnek
Şöyle yaparız
namespace Custom
{
  struct Container
  {
    bool m_empty;
  };

  constexpr bool empty(Container const& c) // custom implementation for our own type
  {
    return c.m_empty;
  }
}

template<class T>
void PrintEmpty(char const* containerName, T&& container)
{
  using namespace std;
  std::cout << containerName << " is " << (empty(container) ? "empty" : "not empty");
}

int main()
{
  PrintEmpty("std::vector<int>()", std::vector<int>());
  PrintEmpty("Container{}", Custom::Container{});
  PrintEmpty("Container{ true }", Custom::Container{ true });
}



7 Şubat 2022 Pazartesi

K&R C - Yani Brian Kernighan and Dennis Ritchie C

Giriş
ANSI C 1989 yılında ortaya çıktı. Bundan daha önceki C türevlerinden bir tanesi de 1987 yılında ortaya çıkan K&R C. Bu türevin en önemli özelliği değişkenlerin nerede tanımlandığı. Değişkenler metodun başında tanımlanıyor.

Örnek
Şöyle yaparız
#include <stdio.h>

int add(a, b)
    int a, b;
{
  return a + b;
}

int main()
{
  printf("%d\n", add(5, 6));
}
Örnek - C89
Açıklaması şöyle
Versions of C up to and including C89 (i.e. the language version standardised in 1989; note this was the last major revision to the C standard before 1999) allowed variables to be declared only at the beginning of a scope, which forces you into the style shown in your first snippet.
Şöyle yaparız
int main()
{
  int i;
    
  for (i=0; i<10; i++)
  {
    printf("hello\n");
  }
    
  return 0;
}


13 Kasım 2021 Cumartesi

libc malloc alternatifleri

Giriş
libc dışında alternatif olarak kullanılabilecek başka heap kütüphaneleri de mevcut.

gnu malloc Problemi Nedir?
Açıklaması şöyle
Under the hood, GNU malloc uses various data structures to make memory allocations more efficient. One such data structure is a collection of heaps. When the application calls malloc, one of these heaps is searched for a contiguous free chunk of memory big enough to fit the request. When the application calls free, a chunk of the heap frees up, which can be reused by a future malloc call. An important detail is that only the topmost chunk of each heap is available for returning to the OS. All empty chunks in the middle of heaps will technically be unused, but still count towards the memory the application is using. This is a very simplified view of what’s happening; check the glibc wiki for a complete overview of GNU malloc internals.
Şeklen şöyle

Bu da aslında bazen fazla bellek kullanılmasına sebep oluyor. Açıklaması şöyle. Kullanılan bellek oranı mallinfo() çağrısı ile görülebilir. gdb ile bağlanıp mallinfo() yapmak gerekiyor.
As you might imagine, there could be many chunks in the malloc heaps just sitting around empty, depending on the pattern of malloc and free calls an application executes. At this point we were wondering if this kind of memory fragmentation could explain the Fulfillment Service’s ever growing memory usage. While investigating possible ways to confirm this, we happened upon an excellent article from the LinkedIn engineering team, describing a problem extremely similar to ours. However, instead of using the gdb-heap tool the LinkedIn team used, we decided to confirm our hypothesis in a slightly more direct way.

It turns out that GNU malloc already exposes some statistics which are suitable for roughly quantifying memory fragmentation. The statistics we are interested in are: the total size of memory in use by the application, the total size of memory in malloc’s heaps but not in use by the application and the part of that memory allowed to be returned to the OS. GNU malloc’s mallinfo function returns these as the uordblks, fordblks and keepcost fields respectively. So, calculating 1 — uordblks / (fordblks — keepcost) gives the ratio of unused memory that cannot be returned to the OS, a measure of memory fragmentation.
Bu çağrının döndürdüğü şey şeklen şöyle

gdb ve java birlikte kullanımı için açıklama şöyle
Having learned this, we created a local testing setup of the Fulfillment Service. This setup consisted of a Docker container with gdb (the GNU debugger for debugging native code), OpenJDK with debug symbols and glibc with debug symbols. This setup allowed us to attach gdb to the JVM and call the mallinfo function from the gdb prompt.

1. jemalloc
github sayfası burada. Açıklaması şöyle. Eğer MALLOC_CONF değişkeni atanırsa, uygulama .heap uzantılı dosyalar üretir, bu dosyalar jeprof komutu ile okunaklı hale getirilebilir.
These two functions, malloc and free, are implemented in their own library. The default on most flavors of Linux is GNU malloc, but it can be swapped out for other implementations. One such implementation is jemalloc, which conveniently also allows tracking where malloc is being called from. This gives us the opportunity to see whether there are any native functions allocating increasing amounts of memory.

On Linux, jemalloc can be enabled by bundling its shared library with an application and setting the LD_PRELOAD environment variable to the location of libjemalloc.so before running Java. Memory profiling can be enabled through the MALLOC_CONF environment variable. The jemalloc wiki contains some useful examples. You can check the jemalloc man page for a full reference of these options. Now our application writes .heap files after a set volume of allocations. These files can be parsed using the jeprof command into something human-readable.
jemalloc ile ilgili bir başka açıklama şöyle. jemalloc tüm malloc() çağrılarını takip etmiyor ancak örnekleme yapıyor.
Jemalloc only samples memory allocations instead of measuring every single malloc call to prevent excessive resource consumption. Therefore, the output of jeprof cannot be directly interpreted as the number of bytes currently in use. However, it does allow us to spot any suspicious functions allocating native memory. Additionally, we could also spot functions that are holding on to significantly more memory relative to others (potentially indicating a memory leak).
Örnek
Şöyle yaparız
export LD_PRELOAD=/usr/local/lib/libjemalloc.so

# tell jemalloc to write a profile to the disk every few 1Gb allocations 
# and record a stack trace (referenced from the blog):
export MALLOC_CONF=prof:true,lg_prof_interval:30,lg_prof_sample:17

# jeprof*.heap. isimli dosyalar oluşur
# dosyalardan rapor oluştur
jeprof --show_bytes --gif /path/to/jvm/bin/java jeprof*.heap > /tmp/app-profiling.gif

2. tcmalloc
Örneğin TCMalloc google tarafından kullanılıyor.

$ LD_PRELOAD="/usr/lib/libtcmalloc.so"yaparak yeniden derlemeye ihtiyaç duymadan kullanılabilir. Açıklaması şöyle.
TCMalloc assigns each thread a thread-local cache. Small allocations are satisfied from the thread-local cache. Objects are moved from central data structures into a thread-local cache as needed, and periodic garbage collections are used to migrate memory back from a thread-local cache into the central data structures.

4 Kasım 2021 Perşembe

std::integral Constraint

Giriş
Bu bir constraint. Açıklaması şöyle
... concept like std::integral constrains the deduced type to be an integral type, such as int or long, but not float, or std::string.

Örnek
Şöyle yaparız
std::integral auto something(){
  return 0;
}

int main(){
  const auto x = something();
  return x;
}

3 Ekim 2021 Pazar

alloca metodu - standart C metodu değildir Kullanmayın

Giriş
Şu satırı dahil ederiz
#include <alloca.h>
Bu metod standart C veya POSIX metodu değildir. Gnu C kütüphanesinde bulunur. Windows'ta ise _alloca() şeklinde kullanılabilir.

Bu metod stack üzerinde yer ayırır. Açıklaması şöyle
The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller.
alloca vs Variable Length Array (VLA)
alloca metodu VLA'dan da eskidir. Açıklaması şöyle. BSD 3 1970'lerin sonuna doğru vardı.
CONFORMING TO

This function is not in POSIX.1-2001.

There is evidence that the alloca() function appeared in 32V, PWB, PWB.2, 3BSD, and 4BSD. There is a man page for it in 4.3BSD. Linux uses the GNU version.
Aslında bu metoda C dilinde gerek yoktur! Çünkü C dili variable length array (VLA) kullanarak stack üzerinde boyutu runtime'da belirlenen yer ayırabilmeye imkan verir.

Ancak C++ variable length array kullanımına izin vermediği için bazen faydalı olabiliyor.
Örnek
alloca yerine VLA kullanılabileceğini görmek için şöyle yaparız
#include <stdio.h>
#include <alloca.h>

void foo(int n)
{
    int a[n];
    int *b=alloca(n*sizeof(int));
    int c[n];
    printf("&a=%p, b=%p, &c=%p\n", (void *)a, (void *)b, (void *)c);
}

int main()
{
    foo(5);
    return 0;
}
Örnek
Örnekte placement new için yer alloca ile stack üzerinde oluşturuluyor.

8 Eylül 2021 Çarşamba

std::isalpha metodu

Giriş
Bu metod ile ASCII karakterlerin alfabetik olup olmadığı belirlenebilir. Bu metod parametre olarak int alır.
int isalpha ( int c );
Ancak c parametresi unsigned char değeri alacak şekilde sınırlandığı için yalnızca ASCII karakterler için çalışır. Açıklaması ise aşağıda.
The c argument is an int, the value of which the application shall ensure is representable as an unsigned char or equal to the value of the macro EOF. If the argument has any other value, the behavior is undefined.