Erreurs, bugs, questions - page 2506

 
Francuz:

Les registres sont mesurés en bits, et non en octets. Cette ligne est donc utilisée de manière incorrecte dans le reste du code :

Non, vous dites quelque chose d'étrange. Je ne vais pas le prouver. Regardez la documentation sur le processeur, lisez ici https://stackoverflow.com/questions/7281699/aligning-to-cache-line-and-knowing-the-cache-line-size/7284876.

Sur x86, les lignes de cache sont de 64 octets

Je n'ai pas besoin de registres, je n'en parle pas du tout.

Aligning to cache line and knowing the cache line size
Aligning to cache line and knowing the cache line size
  • 2011.09.02
  • MetallicPriestMetallicPriest 12.1k2929 gold badges135135 silver badges259259 bronze badges
  • stackoverflow.com
To prevent false sharing, I want to align each element of an array to a cache line. So first I need to know the size of a cache line, so I assign each element that amount of bytes. Secondly I want the start of the array to be aligned to a cache line. I am using Linux and 8-core x86 platform...
 
Vict:

Non, vous dites quelque chose d'étrange. Je ne vais pas le prouver. Regardez la documentation du processeur, lisez ici https://stackoverflow.com/questions/7281699/aligning-to-cache-line-and-knowing-the-cache-line-size/7284876.

Je n'ai pas besoin de registres, je n'en parle pas du tout.

Hmm... Ok. (se racle la gorge) Quoi qu'il en soit, le cache varie d'un modèle à l'autre. Il n'y a aucun moyen de connaître sa taille à partir du logiciel. C'est pourquoi il est stupide de le prendre comme un guide. Mais tous les processeurs ont deux types de registres et c'est sur la taille des registres que les programmeurs qualifiés se concentrent. Et même cette orientation vers les registres n'est pas toujours réussie, car entre le programme et le processeur se trouvent un compilateur et un système d'exploitation.

En outre, cette ligne est calculée de manière incorrecte et sans registres :

int index = int(CACHE_LINE_SIZE - getaddr(data[rndnum].ar[0]) % CACHE_LINE_SIZE) / sizeof(int);
 
Francuz:

Hmm... Ok. De toute façon, le cache varie d'un processeur à l'autre. Et il n'y a aucun moyen de connaître sa taille à partir du logiciel. C'est pourquoi il est stupide de s'en inspirer. Mais tous les processeurs ont deux types de registres et c'est sur la taille des registres que les programmeurs qualifiés se concentrent. Et même le ciblage de la taille du registre ne vous sauve pas toujours, car le compilateur et le système d'exploitation se situent entre le programme et le processeur.

Là encore, les choses évoluent, le multithreading prend de plus en plus d'importance, et voici une bibliothèque cross std pour vous en parler

https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size

De plus, cette ligne est mal calculée et ne tient pas compte des registres :
Peut-être, mais jusqu'à présent vous ne m'avez pas convaincu.
std::hardware_destructive_interference_size, std::hardware_constructive_interference_size - cppreference.com
  • en.cppreference.com
These constants provide a portable way to access the L1 data cache line size.
 
Vict:

Encore une fois non, les choses évoluent, l'accent est mis de plus en plus sur le multithreading, et voilà - la bibliothèque cross std vous dira tout

https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size

Peut-être, mais jusqu'à présent vous ne m'avez pas convaincu.

Il ne vous le dira pas, il vous le dira. Lisez attentivement les spécifications.


Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Peut-être, mais jusqu'à présent vous ne m'avez pas convaincu.

Je ne sais pas exactement quel décalage vous vouliez, mais c'est facile à comprendre : une adresse absolue est totalement inutile dans les calculs. Avez-vous oublié que le point de référence de la mémoire est l'adresse de la structure ? Et vous avez probablement voulu obtenir l'offset d'un tableau dans un bloc de mémoire de structure ? Et c'est ce que la différence entre les adresses de la structure et l'élément nul du tableau s'avère être.

 
Artyom Trishkin:

S'il n'y a pas de valeur dans le tampon sur la barre, elle doit être explicitement écrite dans le tampon. C'est-à-dire, si la valeur calculée doit être sortie dans le tampon - nous l'écrivons dans le tampon, sinon - nous écrivons une valeur vide.

Merci, Artem.

 
Francuz:

Bien que je ne sois pas tout à fait sûr de l'offset que vous vouliez, il est facile de comprendre le bug : une adresse absolue est complètement inutile dans les calculs. Avez-vous oublié que le point de référence mémoire est l'adresse de la structure ? Et vous avez probablement voulu obtenir l'offset d'un tableau dans un bloc de mémoire de structure, n'est-ce pas ? Et c'est la différence entre les adresses de la structure et l'élément zéro du tableau.

int index = int(CACHE_LINE_SIZE - getaddr(data[rndnum].ar[0]) % CACHE_LINE_SIZE) / sizeof(int);
                                3        1                    2                  4

Actions dans l'ordre :

1 - obtient l'adresse du premier élément ar[] dans la structure de données actuelle.

2. trouver ses décalages par rapport au début de la ligne de cache

3. trouver le nombre d'octets entre cette ligne et la fin de la ligne de cache.

4. trouver combien d'octets vont tenir dans cet espace jusqu'à la fin de la ligne de cache.


L'avez-vous fait tourner sur votre ordinateur ? Y a-t-il une différence de vitesse ? Ou c'est juste moi ?

 
Vict:

2. trouver ses décalages par rapport au début de la ligne de cache

Qu'est-ce qui vous fait penser que c'est un moyen de connaître son décalage ?

 
Quelle est la cause de ce ralentissement ?

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bugs, bugs, questions

fxsaber, 2019.07.09 11:13

   Data data[];
   
   ArrayResize(data, 32768);

Il y a un ralentissement de 6x qui se produit !

 
fxsaber:
A quoi servent ces freins ?
Un tableau dynamique a plus de contrôles, Renat a écrit une fois, je ne peux pas trouver le post, juste parler de l'accès à l'index, pourquoi il est significativement plus lent que les plus.
 
Vict:

J'ai mis au point l'idée originale (le premier code ne comptait pas les adresses correctement). Si vous le voulez bien, il sera intéressant de voir le résultat avec vous.

Il y a une grande variation d'une manche à l'autre, je ne peux pas voir la différence dans un sens ou dans l'autre. Bien sûr, j'utilise la version Release.

#define  WRONG_ALIGNED
#define  CACHE_LINE_SIZE 64

struct Data {
#ifdef  WRONG_ALIGNED
   ushort pad;
#else
   uint pad;
#endif
   uint ar[CACHE_LINE_SIZE/sizeof(int)+1];
};

#import "msvcrt.dll"
  long memcpy(uint &, uint &, long);
#import
#define  getaddr(x) memcpy(x, x, 0)

void OnStart()
{
//   Data data[32768];
   Data data[];
  
   ArrayResize(data, 32768); // для не static-массива жуткие тормоза выходят. 
   ZeroMemory(data);
   
   ulong start_time = GetMicrosecondCount();
   
   for(unsigned i = 0; i < 10000; ++ i) {
    for (int j = ArraySize(data) - 1; j >= 0; j--)
    {
         int index = int(CACHE_LINE_SIZE - getaddr(data[j].ar[0]) % CACHE_LINE_SIZE) / sizeof(int);
         ++ data[j].ar[index];
         ++ data[j].pad;
      }
   }
      
   Alert(GetMicrosecondCount() - start_time);
   
//   Print(data[100].ar[0]);
//   Print(data[100].pad);
}
Raison: