Domanda

C'è un, rapido, affidabile modo deterministico (vale a dire non un punto di riferimento) per verificare se l'unità di sistema di Mac OS X è un Solid State Drive?

C'è un altro indicatore di quanto bene disco gestisce accesso parallelo? Sto cercando di regolare il numero di thread che il mio programma sta per utilizzare per le operazioni di disco-bound.

Io non sono interessato a velocità crudo o cerco tempo, solo che tipo di accesso - seriale o parallela - è più veloce per l'unità. Non mi aspetto che gli utenti del mio programma di utilizzare iSCSI o RAID. SSD è il mio obiettivo, tutto il resto è piacevole da avere.

Device Characteristics di IOAHCIBlockStorageDevice contiene tali informazioni. Come posso leggere a livello di codice?


Finora ho capito va in questo modo: (segue è pseudocodice)

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); 
}

Modifica: Ecco il codice sorgente completo . Ho verificato che funziona con Intel SSD e OCZ Vertex.

È stato utile?

Soluzione

Se si sta cercando di ottenere questo tipo di informazioni, sei ipotesi migliore è IOKit.

È possibile provare alcune delle sue funzionalità utilizzando il ioreg strumento a riga di comando o il IORegistryExplorer .


Ecco un po 'di codice che potrebbe aiutare. Si recupera tutti i dischi rigidi che non sono un RAID e non sono partizioni. Questo non è ciò che si vuole, ma potrebbe iniziare.

#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

Altri suggerimenti

In realtà, penso che si dovrebbe andare via comparativa, perché risponde in modo più accurato la tua domanda - non è davvero cura che il disco sembra essere uno SSD, basta cura che il disco è veramente veloce. Che cosa succede se l'utente sta utilizzando una configurazione RAID veloce, o un array di Fibre Channel o iSCSI sta usando?

Basta leggere un po 'di settori casuali dalla sottostante / dev / diskX e se soddisfa le vostre esigenze si può trattare come un disco "Fast"

Questo sembra possibile solo per le unità interne. Non riuscivo a trovare un modo utilizzando IOKit per interrogare un Samsung T5 USB esterna 3 SSD per il suo SSD-ness (né una hddd USB Toshiba Canvio). Sono riuscito per l'unità interna nel mio MBP, però.

utility

Disco inoltre non pensa che la Samsung è uno SSD, in modo che mi fa pensare non ci può essere un modo, diverso da quello di misurare le prestazioni effettive.

Il numero di thread? 1 sta per sopraffare qualsiasi disco, SSD, RAID o meno. Disk è lento, il processore è veloce. Il sistema operativo sta per riordinare le richieste del disco in ogni caso (o almeno dovrebbe) per ottenere i movimenti della testa meno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top