Question

J'utilise ARM926EJS. J'obtiens 20% de vitesse de mémoire en plus dans le test de copie en mémoire, sans Linux (tout comme un exécutable Getting Started). Mais sous Linux, le même code fonctionne 20% plus lentement.

Le code est

 
/// Below code just performs burst mode memcopy test.        
void asmcpy(void *a, void *b, int iSize)
{
   do
  {
    asm volatile (
             "ldmia %0!, {r3-r10} \n\t"
             "stmia %0!, {r3-r10} \n\t"
             :"+r"(a), "+r"(b)
             :
             :"r"(r3),"r"(r4),"r"(r5),"r"(r6),"r"(r7),"r"(r8),"r"(r9),"r"(r10)
             );
  }while(size--)
}

J'ai vérifié qu'aucun autre processus ne prend le temps processeur sous Linux (j'ai vérifié cela à l'aide de la commande time. Il indique que temps réel est identique à temps usr . )

S'il vous plaît, dites-moi quel peut être le problème avec Linux?

Merci & amp; Cordialement.

ajouté:

mon code de test est

int main()
{
  int a[320 * 120], b[320 * 120];

 for(int i=0; i != 10000; i++)
 {
   /// Size is divided by 8 because our memcpy function performs 8 integer load stores in the iteration
   asmcpy(a, b, (320 * 120) / 8);
 }
}

Premiers contacts est un fichier bin envoyé à la RAM via un port série et exécuté directement en accédant à cette adresse dans la RAM. (sans besoin d'un système d'exploitation)

ajouté.

Je n’ai pas vu une telle différence de performances sur les autres processeurs. Ils utilisaient de la mémoire SD, ce processeur utilise DDR Ram. Cela peut-il être une raison?

ajouté.   Le cache de données n'est pas activé lors de la mise en route du code et le cache de données est activé en mode Linux. Donc, idéalement, toutes les données doivent être mises en cache et accessibles sans latence RAM, mais Linux est toujours lent à 20%.

ajouté:   Mon microcontrôleur est LPC3250. Les deux tests ont été testés sur la même RAM DDR externe.

Était-ce utile?

La solution

Cette puce a une MMU, donc Linux l’utilisera probablement pour gérer la mémoire. Peut-être que le simple fait de l'activer introduit un impact sur les performances. En outre, Linux utilise une stratégie d'allocation mémoire paresseuse, affectant uniquement les pages mémoire à un processus lorsqu'il le rencontre pour la première fois. Si vous copiez beaucoup de mémoire, le MMU générera des erreurs de page pour demander au noyau d'allouer une page alors qu'il se trouve dans votre boucle. Sur un processeur bas de gamme, tous ces commutateurs de contexte provoquent des vidages de la mémoire cache et introduisent un ralentissement notable.

Si votre système est suffisamment petit, essayez une version de Linux sans MMU (telle que uClinux ). Peut-être que cela vous permettrait d'utiliser une puce moins chère avec des performances similaires. Sur les systèmes embarqués, chaque centime compte.

mise à jour: quelques détails supplémentaires:

Chaque processus Linux obtient ses propres mappages de mémoire. Au début, cela n'inclut que le noyau et (éventuellement) le code exécutable. Tout le reste de la 4 Go linéaire (sur 32 bits) semble disponible, mais aucune page de RAM ne leur est assignée. Dès que vous lisez ou écrivez une adresse mémoire non allouée, la MMU signale une erreur de page et bascule vers le noyau. Le noyau voit qu'il a encore beaucoup de pages RAM libres. Il en choisit une, l'assigne au point défaillant et revient à votre code, qui termine l'instruction interrompue. La prochaine page n'échouera pas car toute la page (généralement 4 Ko) est déjà assignée; mais quelques itérations plus tard, il atteindra un autre espace non attribué et la MMU appellera à nouveau le noyau.

Autres conseils

Comment effectuez-vous le chronométrage? Il n'y a pas de code de synchronisation dans votre exemple.

Êtes-vous sûr de ne pas mesurer le temps de chargement / déchargement du processus?

La vitesse d'horloge du processeur est-elle la même dans les deux cas?

Si vous utilisez une mémoire SDRAM externe, le minutage de la RAM est-il le même dans les deux cas?

Le cache de données est-il activé dans les deux cas?

Clifford

La mise en route n'est pas "juste un exécutable". Il doit y avoir un code pour définir le registre du contrôleur DDR.

Si le cache est également activé, la MMU doit l'être également. Je pense que sur ARM926EJS, vous ne pouvez pas avoir de cache de données sans MMU.

Je pense que chaque changement de contexte entraîne un vidage du cache, car celui-ci est virtuellement indexé, étiqueté et étiqueté, et que le noyau et l'espace utilisateur ne partagent pas le même espace d'adressage. Vous avez donc probablement beaucoup plus de vidage indésirable du cache sans OS.

Voici un article présentant certains aspects de la coût de vidage du cache VIVT sous Linux

Quel microcontrôleur (et pas uniquement quel processeur ARM) utilisez-vous?

Est-il possible que, dans le cycle autre que Linux, la matrice que vous testez soit en RAM sur le microcontrôleur lui-même alors que dans le test Linux, la matrice en cours de test est en RAM externe? La RAM interne est généralement utilisée beaucoup plus rapidement que la RAM externe. Cela peut expliquer le ralentissement du test Linux, même si la mise en cache des données est activée uniquement pour l'exécution Linux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top