Pergunta

Existe uma maneira confiável, rápida e determinística (ou seja, não um benchmark) para verificar se o sistema de acionamento Mac OS X está ligado é uma unidade de estado sólido?

Existe algum outro indicador de quão bem o disco lida com acesso paralelo? Estou tentando ajustar o número de threads que meu programa usará para operações ligadas ao disco.

Não estou interessado em velocidade bruta ou em busca de tempo, apenas que tipo de acesso - serial ou paralelo - é mais rápido para a unidade. Não espero que os usuários do meu programa usem ISCSI ou RAID. O SSD é o meu foco, qualquer outra coisa é agradável de se ter.

Device Characteristics do IOAHCIBlockStorageDevice contém essas informações. Como posso ler programaticamente?


Até agora eu descobri que é assim: (a seguir é pseudocode)

match = IOBSDNameMatching(kIOMasterPortDefault,0,"disk0s2");
IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iterator);
while(entry = IOIteratorNext(iterator)) {
   do {
     entry = IORegistryEntryGetParentEntry(nextMedia, kIOServicePlane, &entry);
     dict = IORegistryEntryCreateCFProperty(nextMedia, 
            CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, 0);
     [dict objectForKey:CFSTR(kIOPropertyMediumTypeKey)];
   } 
   while(!dict && entry); 
}

Editar: Aqui está o código -fonte completo. Eu verifiquei que funciona com o Intel SSD e o OCZ Vertex.

Foi útil?

Solução

Se você está tentando obter esse tipo de informação, é o melhor palpite.

Você pode tentar algumas de sua funcionalidade usando o IOREG ferramenta de linha de comando ou o IoregistryExplorer.


Aqui está algum código que pode ajudá -lo. Ele busca todos os discos rígidos que não são um ataque e não são partições. Não é isso que você quer, mas pode começar.

#import "TWDevice.h"

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <paths.h>
#include <sys/param.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/Kext/KextManager.h>


@implementation TWDevice

@synthesize name, devicePath, size, blockSize, writable, icon;

+ (NSArray *)allDevices {
    // create matching dictionary
    CFMutableDictionaryRef classesToMatch;
    classesToMatch = IOServiceMatching(kIOMediaClass);
    if (classesToMatch == NULL) {
        [NSException raise:@"TWError" format:@"Classes to match could not be created"];
    }

    // get iterator of matching services
    io_iterator_t mediaIterator;
    kern_return_t kernResult;
    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
                                                                      classesToMatch,
                                                                      &mediaIterator);

    if (kernResult != KERN_SUCCESS) {
        [NSException raise:@"TWError" format:@"Matching services did not succed."];
    }

    // iterate over all found medias
    io_object_t nextMedia;
    NSMutableArray *detectedDevices = [NSMutableArray array];
    while (nextMedia = IOIteratorNext(mediaIterator)) {
        NSMutableDictionary *properties;
        kernResult = IORegistryEntryCreateCFProperties(nextMedia,
                                                                                  (CFMutableDictionaryRef *)&properties,
                                                                                  kCFAllocatorDefault, 0);

        if (kernResult != KERN_SUCCESS) {
            [NSException raise:@"TWError" format:@"Getting properties threw error."];
        }

        // is it a whole device or just a partition?
        if ([[properties valueForKey:@"Whole"] boolValue] &&
            ![[properties valueForKey:@"RAID"] boolValue]) {
            TWDevice *device = [[[TWDevice alloc] init] autorelease];

            device.devicePath = [NSString stringWithFormat:@"%sr%@", _PATH_DEV, [properties valueForKey:@"BSD Name"]];
            device.blockSize = [[properties valueForKey:@"Preferred Block Size"] unsignedLongLongValue];
            device.writable = [[properties valueForKey:@"Writable"] boolValue];
            device.size = [[properties valueForKey:@"Size"] unsignedLongLongValue];

            io_name_t name;
            IORegistryEntryGetName(nextMedia, name);
            device.name = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

            …

            [detectedDevices addObject:device];
        }

        // tidy up
        IOObjectRelease(nextMedia);
        CFRelease(properties);
    }
    IOObjectRelease(mediaIterator);

    return detectedDevices;
}

@end

Outras dicas

Na verdade, acho que você deveria seguir a rota de benchmarking, porque ele responde com mais precisão sua pergunta - você não verdade Cuidado com o fato de o disco ser um SSD, você só se importa que o disco seja realmente rápido. E se o usuário estiver usando uma configuração rápida do RAID, ou uma matriz de canal de fibra, ou estiver usando ISCSI?

Basta ler vários setores aleatórios do subjacente /dev /diskx e se atender aos seus requisitos, você poderá tratá -lo como uma unidade "rápida"

Isso só parece possível para unidades internas. Não consegui encontrar uma maneira de usar o IOKIT para consultar um SSD externo USB 3 do Samsung T5 por seu SSD-NESS (nem um Toshiba Canvio USB HDDD). Eu gerenciei a unidade interna no meu MBP, no entanto.

O utilitário de disco também não acha que o Samsung seja um SSD, o que me faz pensar que pode não haver uma maneira, além de medir o desempenho real.

O número de threads? 1 vai sobrecarregar qualquer disco, SSD, RAID ou não. O disco é lento, o processador é rápido. O sistema operacional vai reordenar suas solicitações de disco de qualquer maneira (ou pelo menos deveria) para obter os menores movimentos da cabeça.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top