Вопрос

Существует ли надежный, быстрый и детерминированный способ (т. нет тест), чтобы проверить, является ли системный диск Mac OS X твердотельным накопителем?

Есть ли какой-нибудь другой индикатор того, насколько хорошо диск обрабатывает параллельный доступ?Я пытаюсь настроить количество потоков, которые моя программа будет использовать для операций с диском.

Меня не интересует чистая скорость или время поиска, а только какой тип доступа – последовательный или параллельный – быстрее для привода.Я не ожидаю, что пользователи моей программы будут использовать iSCSI или RAID.SSD — это мое основное внимание, все остальное приятно иметь.

Device Characteristics из IOAHCIBlockStorageDevice содержит эту информацию.Как я могу прочитать это программно?


Пока я понял, что это происходит так:(ниже приведен псевдокод)

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

Редактировать: Вот полный исходный код.Я проверил, что он работает с твердотельными накопителями Intel и OCZ Vertex.

Это было полезно?

Решение

Если вы пытаетесь получить такую ​​информацию, лучше всего предположить, что это IOKit.

Вы можете попробовать некоторые из его функций, используя Йорег инструмент командной строки или IORegistryExplorer.


Вот код, который может вам помочь.Он извлекает все жесткие диски, которые не являются RAID и не являются разделами.Это не то, что вам нужно, но это может помочь вам начать.

#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

Другие советы

На самом деле, я думаю, что вы должны пойти по маршруту сравнительного анализа, потому что он более точно отвечает на ваш вопрос - вы не В самом деле заботитесь о том, что диск оказался SSD, вы просто заботитесь о том, что диск действительно быстрый. Что если пользователь использует быструю настройку RAID, или массив волоконно -волоконного канала, или использует ISCSI?

Просто прочитайте кучу случайных секторов из базового /dev /diskx, и если он соответствует вашим требованиям, вы можете рассматривать его как «быстрый» диск

Это кажется возможным только для внутренних дисков. Я не смог найти способ использования iokit для запроса внешнего SSD SSD Samsung T5 для его SSD (ни Toshiba Canvio USB HDDD). Хотя я справился с внутренним диском в моем MBP.

Утилита диска также не думает, что Samsung является SSD, поэтому я думаю, что не может быть, кроме как измерить фактическую производительность.

Количество потоков? 1 собирается сокрушить любой диск, SSD, RAID или нет. Диск медленный, процессор быстрый. ОС в любом случае будет переупорядочить ваши запросы на диск (или, по крайней мере, она должна), чтобы получить наименьшие движения головы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top